Tag Archives: freebsd

FreeBSD 13.2 on ThinkPad T14 (GEN1)

I used to run FreeBSD on older laptops – some more then a decade old – like my favorite ThinkPad W520 daily driver or ThinkPad X220 mobile companion. Today I will share with you my experiences of running latest production ready FreeBSD 13.2-RELEASE system on a quite modern ThinkPad T14 (GEN1) from 2021/2022 (depending on the source of the information) – which is quite new I would say.

… do not interpret this article wrong – The W520 and X220 (sometimes T420s) are still my daily/mobile/… drivers and my points explained in the Epitaph to Laptops article remain the same. I just had an opportunity to use ThinkPad T14 for several days so I thought it would be a good idea to check and document FreeBSD behavior on it.

In many parts this article will be a copy cat of the earlier FreeBSD 13.1 on ThinkPad W520 article – as the topic and configs are mostly the same – you have been warned πŸ™‚

ThinkPad T14 (GEN1)

As the ThinkPad T490 was released Lenovo needed to rethink their naming convention as the next one could have been ThinkPad T4100 (like 100 is after 90) or something different as T500 was already taken by older model … their new naming scheme is not bad – definitely better then their idea of newer keyboard layout after ditching the 7-row keyboard from 2011 and earlier models.

The model I was able to test on had quad core Intel i5-10210U model CPU which is somewhere between 25-35% faster (according to benchmarks) then the Intel i7-2860QM CPU from my ThinkPad W520. Not bad – especially knowing that the time span between their releases is 9 years … but to be honest – in real usage I do not feel that 25-35% more speed.

T14 % lscpu
Architecture:            amd64
Byte Order:              Little Endian
Total CPU(s):            8
Thread(s) per core:      2
Core(s) per socket:      4
Socket(s):               1
Vendor:                  GenuineIntel
CPU family:              6
Model:                   142
Model name:              Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz
Stepping:                12
L1d cache:               32K
L1i cache:               32K
L2 cache:                256K
L3 cache:                6M
Flags:                   fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36
                         cflsh ds acpi mmx fxsr sse sse2 ss htt tm pbe sse3 pclmulqdq dtes64
                         monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1
                         sse4_2 x2apic movbe popcnt tsc_deadline aes xsave osxsave avx f16c rdrnd
                         fsgsbase tsc_adjust sgx bmi1 avx2 smep bmi2 erms invpcid fpcsds mpx rdseed
                         adx smap clflushopt intel_pt syscall nx pdpe1gb rdtscp lm lahf_lm lzcnt

Below you can see how ThinkPad T14 (GEN1) looks like.

thinkpad-t14

To be honest I would even prefer to use ThinkPad SK-8855 USB keyboard as showed here below.

T14s-keyboard-upgraded

Specifications

Below You will find specs of this machine.

CPU: Intel Core i5-10210U (4C/8T) 14nm
RAM: 16 GB (2 * 8GB DDR4)
HDD0: 256GB WD Black SN750 M.2 [nvd(4)]
GFX0: Intel UHD Graphics (integrated) [graphics/drm-kmod]
SCR: 14.1 1920x1080 Touch Screen
USB: 2 x USB-A 3.0 + 1 x USB-C 3.0 [ehci(4) + xhci(4)]
AUDIO: Realtek ALC257 [snd_hda(4)]
PORTS: 1 x HDMI
SD: microSD Card Reader [sdhci(4)]
LAN: 10/100/1000 Intel I219-V Gigabit [em(4)]
WIFI: Intel Comet Lake PCH-LP CNVi WiFi 802.11ax [iwlwifi(4)]
CAM: Webcam 720p [multimedia/webcamd]

I have uploaded the https://bsd-hardware.info/ probe of that ThinkPad T14 to their database and its available – https://bsd-hardware.info/?probe=8aede62ca8 – here.

After messing with this laptop for a while I can tell you that in most areas its on par with mine ThinkPad W520 laptop. The battery time is similar (about 5 hours). The suspend/resume works when you use X11 with graphics/drm-kmod package. Even the touch screen works like a charm – the same as my other ThinkPad X220t (tablet) … and even no additional configuration was needed – I just used the configuration that I use daily on my ThinkPad W520 laptop. But … the WiFi does not work πŸ™‚ While iwlwifi(4) properly attaches to this card the wpa_supplicant(8) is just not able to connect to the Access Point. There are at least several ways on how to Cope with WiFi Fuckup on FreeBSD – feel free to check them out. I used my favorite fallback solution – Realtek RTL8188CUS USB dongle and that one worked really well with rtwn(4) driver.

FreeBSD System Configuration

From many things that I really like about FreeBSD (more here – Quare FreeBSD? – in separate article) is that it can be entirely configured using just 3 files. This configuration already features all power management settings that I described in the The Power to Serve – FreeBSD Power Management article.

I installed FreeBSD in a pretty standard way with GELI encryption enabled and with ZFS as the filesystem. When in doubt the installation procedure is described in the FreeBSD Desktop – Part 2.1 – Install FreeBSD 12 article.

Main FreeBSD configuration files.

  • /etc/rc.conf – to system services
  • /etc/sysctl.conf – for runtime parameters
  • /boot/loader.conf – for parameters configurable at boot

I will also include these as their are also crucial for the configuration:

  • /etc/devfs.rules – devices configuration/li>
  • /etc/fstab – filesystems configuration
  • /etc/ttys – terminal initialization configuration
  • /etc/wpa_supplicant.conf – WiFi configuration
  • /usr/local/etc/automount.confautomount(8) configuration
  • /usr/local/etc/doas.confdoas(1) configuration
  • Groups membership.

First the main /etc/rc.conf configuration file.

% cat /etc/rc.conf
# SILENCE # ------------------------------------------------------------------
  rc_startmsgs=NO

# NETWORK # ------------------------------------------------------------------
  hostname=t14.local
  background_dhclient=YES
  extra_netfs_types=NFS
  wlans_rtwn0=wlan0
  create_args_wlan0="country PL regdomain FCC4"
  ifconfig_wlan0="WPA SYNCDHCP"
  defaultroute_delay=3
  defaultroute_carrier_delay=3
  gateway_enable=YES
  harvest_mask=351
  rtsol_flags="-i"
  rtsold_flags="-a -i"

# MODULES/COMMON/BASE # ------------------------------------------------------
  kld_list="${kld_list} /boot/modules/i915kms.ko"
  kld_list="${kld_list} fusefs coretemp sem cpuctl ichsmb cuse"
  kld_list="${kld_list} libiconv cd9660_iconv msdosfs_iconv udf_iconv"

# MODULES/VIRTUALBOX # -------------------------------------------------------
  vboxnet_enable=YES
  kld_list="${kld_list} vboxdrv vboxnetadp vboxnetflt"

# POWER
  performance_cx_lowest=C1
  economy_cx_lowest=Cmax
  powerd_enable=YES
  powerd_flags="-n adaptive -a hiadaptive -b adaptive -m 800 -M 2000"

# DAEMONS | yes # ------------------------------------------------------------
  zfs_enable=YES
  xdm_enable=YES
  xdm_tty=ttyv4
  nfs_client_enable=YES
  ubuntu_enable=YES
  moused_enable=YES
  syslogd_flags='-s -s'
  sshd_enable=YES
  local_unbound_enable=YES
  webcamd_enable=YES
  rctl_enable=YES

# DAEMONS | no # -------------------------------------------------------------
  linux_enable=NO
  sendmail_enable=NONE
  sendmail_submit_enable=NO
  sendmail_outbound_enable=NO
  sendmail_msp_queue_enable=NO

# FS # -----------------------------------------------------------------------
  fsck_y_enable=YES
  clear_tmp_enable=YES
  clear_tmp_X=YES
  growfs_enable=YES

# OTHER # --------------------------------------------------------------------
  keyrate=fast
  keymap=pl.kbd
  virecover_enable=NO
  update_motd=NO
  devfs_system_ruleset=desktop
  hostid_enable=NO
  savecore_enable=NO

Now the runtime parameters /etc/sysctl.conf file.

% cat /etc/sysctl.conf
# SECURITY
  security.bsd.see_jail_proc=0
  security.bsd.unprivileged_proc_debug=0

# SECURITY/RANDOM PID
  kern.randompid=1

# ANNOYING THINGS
  vfs.usermount=1
  kern.coredump=0
  hw.syscons.bell=0
  kern.vt.enable_bell=0

# ZFS DELETE FUCKUP TRIM (DEFAULT: 64)
  vfs.zfs.vdev.trim_max_active=1

# ZFS ARC TUNING
  vfs.zfs.arc.min=134217728
  vfs.zfs.arc.max=536870912

# ZFS ARC FREE ENFORCE @ 1024 \* 1024 \* 3
  vfs.zfs.arc_free_target=3145728

# JAILS/ALLOW UPGRADES IN JAILS
  security.jail.chflags_allowed=1

# JAILS/ALLOW RAW SOCKETS
  security.jail.allow_raw_sockets=1

# DESKTOP/INTERACTIVITY
  kern.sched.preempt_thresh=224

# DESKTOP QUANTUM FOR TIMESHARE THREADS IN stathz TICKS (12) NomadBSD
  kern.sched.slice=3

# DESKTOP/IRIDIUM/CHROMIUM
  kern.ipc.shm_allow_removed=1

# SAMPLE RATE CONVERTER QUALITY (0=low .. 4=high) (1) NomadBSD
  hw.snd.feeder_rate_quality=3

# PERFORMANCE/ALL SHARED MEMORY SEGMENTS WILL BE MAPPED TO UNPAGEABLE RAM
  kern.ipc.shm_use_phys=1

# VIRTUALBOX aio(4) SETTINGS
  vfs.aio.max_buf_aio=8192
  vfs.aio.max_aio_queue_per_proc=65536
  vfs.aio.max_aio_per_proc=8192
  vfs.aio.max_aio_queue=65536

# POWER CONSUMPTION / SILENT FANS Intel 6th GEN+ / ONE LINE FOR EACH TH
# DETAILS IN THE hwpstate_intel(4) MAN PAGE
  dev.hwpstate_intel.0.epp=100
  dev.hwpstate_intel.1.epp=100
  dev.hwpstate_intel.2.epp=100
  dev.hwpstate_intel.3.epp=100
  dev.hwpstate_intel.4.epp=100
  dev.hwpstate_intel.5.epp=100
  dev.hwpstate_intel.6.epp=100
  dev.hwpstate_intel.7.epp=100

# NETWORK/DO NOT SEND RST ON SEGMENTS TO CLOSED PORTS
  net.inet.tcp.blackhole=2

# NETWORK/DO NOT SEND PORT UNREACHABLES FOR REFUSED CONNECTS
  net.inet.udp.blackhole=1

# NETWORK/LIMIT ON SYN/ACK RETRANSMISSIONS (3)
  net.inet.tcp.syncache.rexmtlimit=0

# NETWORK/USE TCP SYN COOKIES IF THE SYNCACHE OVERFLOWS (1)
  net.inet.tcp.syncookies=0

# NETWORK/ASSIGN RANDOM ip_id VALUES (0)
  net.inet.ip.random_id=1

# NETWORK/ENABLE SENDING IP REDIRECTS (1)
  net.inet.ip.redirect=0

# NETWORK/IGNORE ICMP REDIRECTS (0)
  net.inet.icmp.drop_redirect=1

# NETWORK/DROP TCP PACKETS WITH SYN+FIN SET (0)
  net.inet.tcp.drop_synfin=1

# NETWORK/RECYCLE CLOSED FIN_WAIT_2 CONNECTIONS FASTER (0)
  net.inet.tcp.fast_finwait2_recycle=1

# NETWORK/CERTAIN ICMP UNREACHABLE MESSAGES MAY ABORT CONNECTIONS IN SYN_SENT (1)
  net.inet.tcp.icmp_may_rst=0

The biggest difference for ThinkPad T14 against the ThinkPad W520 is this part below.

# POWER CONSUMPTION / SILENT FANS Intel 6th GEN+ / ONE LINE FOR EACH TH
# DETAILS IN THE hwpstate_intel(4) MAN PAGE
  dev.hwpstate_intel.0.epp=100
  dev.hwpstate_intel.1.epp=100
  dev.hwpstate_intel.2.epp=100
  dev.hwpstate_intel.3.epp=100
  dev.hwpstate_intel.4.epp=100
  dev.hwpstate_intel.5.epp=100
  dev.hwpstate_intel.6.epp=100
  dev.hwpstate_intel.7.epp=100

It was not needed/non existent on the ThinkPad W520 hardware.

Now the boot parameters /boot/loader.conf file.

% cat /boot/loader.conf
# CONSOLE COMMON
  autoboot_delay=2       # OPT. '-1' => NO WAIT | OPT. 'NO' => INFINITE WAIT
  hw.usb.no_boot_wait=1  # DO NOT WAIT FOR USB DEVICES FOR ROOT (/) FILESYSTEM
  boot_mute=YES          # LIKE '-m' IN LOADER - MUTE CONSOLE WITH FreeBSD LOGO
  loader_logo=none       # DESIRED LOGO OPTIONS: fbsdbw beastiebw beastie none
  loader_menu_frame="none"
  screen.font="6x12"

# CONSOLE RESOLUTION
  kern.vt.fb.default.mode="1920x1080"
  efi_max_resolution="1920x1080"

# WINE FIX
  machdep.max_ldt_segment=2048

# MODULES - BOOT
  aesni_load=YES
  geom_eli_load=YES
  cryptodev_load=YES
  zfs_load=YES

# drm-kmod PACKAGE - USE SEMAPHORES FOR INTER-RING SYNC
  compat.linuxkpi.semaphores=1

# drm-kmod PACKAGE - ENABLE POWER-SAVING RENDER C-STATE 6
  compat.linuxkpi.enable_rc6=7

# drm-kmod PACKAGE - ENABLE POWER-SAVING DISPLAY C-STATES
  compat.linuxkpi.enable_dc=2

# drm-kmod PACKAGE - ENABLE FRAME BUFFER COMPRESSION FOR POWER SAVINGS
  compat.linuxkpi.enable_fbc=1

# ENABLE SYNAPTICS
  hw.psm.synaptics_support=1

# DISABLE /dev/diskid/* ENTRIES FOR DISKS
  kern.geom.label.disk_ident.enable=0

# DISABLE /dev/gptid/* ENTRIES FOR DISKS
  kern.geom.label.gptid.enable=0

# TERMINAL vt(4) COLORS
  kern.vt.color.0.rgb="#000000"
  kern.vt.color.1.rgb="#dc322f"
  kern.vt.color.2.rgb="#859900"
  kern.vt.color.3.rgb="#b58900"
  kern.vt.color.4.rgb="#268bd2"
  kern.vt.color.5.rgb="#ec0048"
  kern.vt.color.6.rgb="#2aa198"
  kern.vt.color.7.rgb="#94a3a5"
  kern.vt.color.8.rgb="#586e75"
  kern.vt.color.9.rgb="#cb4b16"
  kern.vt.color.10.rgb="#859900"
  kern.vt.color.11.rgb="#b58900"
  kern.vt.color.12.rgb="#268bd2"
  kern.vt.color.13.rgb="#d33682"
  kern.vt.color.14.rgb="#2aa198"
  kern.vt.color.15.rgb="#6c71c4"

# RACCT/RCTL RESOURCE LIMITS
  kern.racct.enable=1

# DISABLE ZFS PREFETCH
  vfs.zfs.prefetch_disable=1

# POWER MGMT / POWER OFF DEVICES WITHOUT ATTACHED DRIVER
  hw.pci.do_power_nodriver=3

# POWER MANAGEMENT FOR EVERY USED AHCI CHANNEL (ahcich 0-7)
  hint.ahcich.0.pm_level=5
  hint.ahcich.1.pm_level=5
  hint.ahcich.2.pm_level=5
  hint.ahcich.3.pm_level=5
  hint.ahcich.4.pm_level=5
  hint.ahcich.5.pm_level=5
  hint.ahcich.6.pm_level=5
  hint.ahcich.7.pm_level=5

# GELI THREADS
  kern.geom.eli.threads=4

Now the mentioned /etc/devfs.rules file.

% cat /etc/devfs.rules
[desktop=10]
add path 'acd*'      mode 0660 group operator
add path 'cd*'       mode 0660 group operator
add path 'da*'       mode 0660 group operator
add path 'pass*'     mode 0660 group operator
add path 'xpt*'      mode 0660 group operator
add path 'fd*'       mode 0660 group operator
add path 'md*'       mode 0660 group operator
add path 'uscanner*' mode 0660 group operator
add path 'lpt*'      mode 0660 group cups
add path 'ulpt*'     mode 0660 group cups
add path 'unlpt*'    mode 0660 group cups
add path 'ugen*'     mode 0660 group operator
add path 'usb/*'     mode 0660 group operator
add path 'video*'    mode 0660 group operator
add path 'cuse*'     mode 0660 group operator

Filesystems and SWAP configuration.

% cat /etc/fstab
# SWAP
  /dev/gpt/swap0  none  swap  sw  0 0

# FreeBSD PSEUDO - NEEDED BY wine(1)
  procfs  /proc  procfs  rw  0 0

# Ubuntu Linux PSEUDO
  linprocfs  /compat/ubuntu/proc     linprocfs  rw,late                    0 0
  linsysfs   /compat/ubuntu/sys      linsysfs   rw,late                    0 0
  devfs      /compat/ubuntu/dev      devfs      rw,late                    0 0
  fdescfs    /compat/ubuntu/dev/fd   fdescfs    rw,late,linrdlnk           0 0
  tmpfs      /compat/ubuntu/dev/shm  tmpfs      rw,late,size=1g,mode=1777  0 0
  /home      /compat/ubuntu/home     nullfs     rw,late                    0 0
  /tmp       /compat/ubuntu/tmp      nullfs     rw,late                    0 0

Terminals configuration under /etc/ttys file. Important part is the ttyv4 entry to match the xdm_tty=ttyv4 value from /etc/rc.conf file.

% grep '^[^#]' /etc/ttys | cat
console none                            unknown off insecure
ttyv0   "/usr/libexec/getty Pc"         xterm   onifexists secure
ttyv1   "/usr/libexec/getty Pc"         xterm   onifexists secure
ttyv2   "/usr/libexec/getty Pc"         xterm   onifexists secure
ttyv3   "/usr/libexec/getty Pc"         xterm   onifexists secure
ttyv4   "/usr/libexec/getty Pc"         xterm   off secure
ttyv5   "/usr/libexec/getty Pc"         xterm   off secure
ttyv6   "/usr/libexec/getty Pc"         xterm   off secure
ttyv7   "/usr/libexec/getty Pc"         xterm   off secure
ttyv4   "/usr/local/bin/xdm -nodaemon"  xterm   off secure
ttyu0   "/usr/libexec/getty 3wire"      vt100   onifconsole secure
ttyu1   "/usr/libexec/getty 3wire"      vt100   onifconsole secure
ttyu2   "/usr/libexec/getty 3wire"      vt100   onifconsole secure
ttyu3   "/usr/libexec/getty 3wire"      vt100   onifconsole secure
dcons   "/usr/libexec/getty std.9600"   vt100   off secure
xc0     "/usr/libexec/getty Pc"         xterm   onifconsole secure
rcons   "/usr/libexec/getty std.9600"   vt100   onifconsole secure

I kept wireless config in /etc/rc.conf file this time – it does conflicts with my own network.sh solution to connect to various both wire and wireless networks – FreeBSD Network Management with network.sh Script – described in details here.

# cat /etc/wpa_supplicant.conf
# GENERAL
eapol_version=2
ap_scan=1
fast_reauth=1

# OPEN NETWORKS
network={
  key_mgmt=NONE
  priority=0
}

# NETWORK WITH HIDDEN SSID
network={
  scan_ssid=1
  ssid="hidden-network"
  psk="12341234"
  priority=0
}

# NAMED OPEN NETWORK
network={
  ssid="Free_Internet"
  key_mgmt=NONE
  priority=0
}

# NORMAL WPA/WPA2 SECURED NETWORK
network={
  ssid="SECURED"
  psk="12345678"
}

The automount(8) config.

% cat /usr/local/etc/automount.conf
  USERUMOUNT=YES
  USER=vermaden
  FM='caja --no-desktop'
  NICENAMES=YES

The doas(1) configuration.

# cat /usr/local/etc/doas.conf
# CORE
  permit nopass keepenv root     as root
  permit nopass keepenv vermaden as root

# THE network.sh SCRIPT
  # pw groupmod network -m YOURUSERNAME
  # cat /usr/local/etc/doas.conf
  permit nopass :network as root cmd /etc/rc.d/netif args onerestart
  permit nopass :network as root cmd /usr/sbin/service args squid onerestart
  permit nopass :network as root cmd dhclient
  permit nopass :network as root cmd ifconfig
  permit nopass :network as root cmd killall args -9 dhclient
  permit nopass :network as root cmd killall args -9 ppp
  permit nopass :network as root cmd killall args -9 wpa_supplicant
  permit nopass :network as root cmd ppp
  permit nopass :network as root cmd route
  permit nopass :network as root cmd tee args -a /etc/resolv.conf
  permit nopass :network as root cmd tee args /etc/resolv.conf
  permit nopass :network as root cmd umount
  permit nopass :network as root cmd wpa_supplicant

Groups I am member of.

% id vermaden | tr ' ' '\n' | tr ',' '\n'
uid=1000(vermaden)
gid=1000(vermaden)
groups=1000(vermaden)
0(wheel)
5(operator)
44(video)
69(network)
145(webcamd)
920(vboxusers)

I also do not rely on ‘stock’ fan speeds and set my own speeds according to CPU temperature with acpi-thinkpad-fan.sh script.

X11

While X11 did not need any custom configuration and it worked out of the box – I have done two things to make it work slightly differently.

First one is to allow CTRL+ALT+BACKSPACE fast way to restart X11.

t14 % cat /usr/local/etc/X11/xorg.conf.d/flags.conf
Section "ServerFlags"
  Option "DontZap" "off"
EndSection

The other one is to enable Tap to Click and Natural Scrolling on a Synaptics touchpad.

t14 % cat /usr/local/etc/X11/xorg.conf.d/touchpad.conf
Section "InputClass"
  Identifier "touchpad"
  MatchIsTouchpad "on"
  Driver "libinput"
  Option "Tapping" "on"
  Option "NaturalScrolling" "on"
EndSection

Comparison to ThinkPad W520

I compared the two laptops. While ThinkPad W520 is heavy and bulky the ThinkPad T14 (GEN1) is light and slim. They both have similar 5 hours battery time on FreeBSD.

You can see the screen brightness comparison between these two below.

LARGE-compare-screen-brightness

The ThinkPad T14 (GEN1) has several flavors of the FullHD screen – check reviews and specs for details. For the record – ThinkPad W520 is on the left.

Below you will find size comparisons.

The view from the top.

LARGE-compare-top

View from the side.

LARGE-compare-side

… and from the side one over another.

LARGE-compare-over

Desktop Environment

Openbox

As for the ‘desktop environment’ that I use – its my custom setup with Openbox along with tools like Tint2 and Dzen2 – for the most basic setup. The screenshot is from FreeBSD 11.1 but it looks exactly the same today.

freebsd-desktop-2019-04

I described this setup in details in the entire FreeBSD Desktop series.

XFCE

I have also tried XFCE – I liked it especially with the Global Menu appmenu plugin. You go this way with this XFCE Cupertino Way handy guide.

xfce-ghostbsd

GNOME

I also tried GNOME for a test – it did not suit me well so I went back to my Openbox setup – but You may find it more comfortable to use. Here is the FreeBSD GNOME 3 Fast Track article that will help you with that.

gnome-8-fixed

Temperatures

I used mine sensors.sh script for that – results below.

t14 # sensors.sh

            BATTERY/AC/TIME/FAN/SPEED
 ------------------------------------
             dev.acpi_ibm.0.fan_level: 1
             dev.acpi_ibm.0.fan_speed: 65535
                   dev.acpi_ibm.0.fan: 0
               dev.cpu.0.cx_supported: C1/1/1 C2/2/151 C3/3/1034
                   dev.cpu.0.cx_usage: 9.02% 35.95% 55.02% last 35us
                       dev.cpu.0.freq: 802
                       hw.acpi.acline: 0
                 hw.acpi.battery.life: 99
                 hw.acpi.battery.time: 275
                hw.acpi.cpu.cx_lowest: C8
                            powerd(8): running

                  SYSTEM/TEMPERATURES
 ------------------------------------
                dev.cpu.0.temperature: 38.0C (max: 100.0C)
                dev.cpu.1.temperature: 39.0C (max: 100.0C)
                dev.cpu.2.temperature: 39.0C (max: 100.0C)
                dev.cpu.3.temperature: 39.0C (max: 100.0C)
                dev.cpu.4.temperature: 40.0C (max: 100.0C)
                dev.cpu.5.temperature: 41.0C (max: 100.0C)
                dev.cpu.6.temperature: 38.0C (max: 100.0C)
                dev.cpu.7.temperature: 38.0C (max: 100.0C)
           dev.pchtherm.0.temperature: 46.0C
      hw.acpi.thermal.tz0.temperature: 46.1C (max: 128.1C)

                   DISKS/TEMPERATURES
 ------------------------------------
             smart.nvme0.temperature:: 44.0C

Accessories

There are some accessories that are very handy with the ThinkPad T14 laptop – I will describe them below.

Power Supply

You can use the default ThinkPad T14 power supply and you can also use any USB-C power delivery charger – that is nice addition.

Mouse Companion

After checking many mouse models – as described in the UNIX Mouse Shootout article – I finally settled with Logitech Triathlon M720 mouse. I have plugged the Lenovo USB Receiver into the back ‘powered’ USB port. While I use that mouse over the USB receiver you can also connect it using Bluetooth – also to other computers. This mouse has a special dedicated button to switch between 3 different computers. Unfortunately the copy-paste between them does not work πŸ™‚

mouse-M720

Battery

Some battery details below.

t14 % acpiconf -i 0
Design capacity:        50450 mWh
Last full capacity:     45760 mWh
Technology:             secondary (rechargeable)
Battery Swappable Capability:   Non-swappable
Design voltage:         11520 mV
Capacity (warn):        2288 mWh
Capacity (low):         200 mWh
Cycle Count:            204
Mesurement Accuracy:    95 %
Max Average Interval:   1000 ms
Min Average Interval:   500 ms
Low/warn granularity:   -1 mWh
Warn/full granularity:  -1 mWh
Model number:           5B10W13906
Serial number:           1071
Type:                   LiP
OEM info:               SMP
State:                  discharging
Remaining capacity:     99%
Remaining time:         4:31
Present rate:           10094 mW
Present voltage:        12681 mV

Experience

Today I ‘recognize’ three laptop keyboard layouts.

  • Best in class 7-row keyboards with INS/DEL and HOME/END and PGUP/PGDN keys block on the right top side.
  • Least PITA ThinkPad T14 like keyboards where PGUP/PGDN keys are in the ARROWS area and HOME/END/INS/DEL block is provided on the top right part.
  • Everything else that I treat like shit.

My fingers do not remember this HOME/END/INS/DEL block that much well – but at its still several ways of magnitude better then any Macbook keyboard layout.

Summary

I will still use mine ThinkPad W520 daily – I still do not need to move to other/less old laptop.

As you can see FreeBSD works quite well with modern laptops – hope someone can find that article useful.

EOF

Simple FreeBSD Poudriere Harvester Guide

The Poudriere is one of the topics I kinda omitted. I thought that official pkg(8) packages are more then enough and that occasional needed package recompilations are not the reasons to use a harvester such as Poudriere for that task. What was my needed recompilations? Usually the audio/lame because FreeBSD did not provided package for it for more then a decade while OpenBSD did … and multimedia/ffmpeg just to include that lame(1) support. Also at the beginning of exFAT format the sysutils/exfat-utils and sysutils/fusefs-exfat needed to be built by hand because of additional license agreement.

logo-freebsd

The Table of Contents for this article:

  • Poudriere Name
  • Poudriere Features
  • FreeBSD Host Setup
  • Poudriere Setup
  • Poudriere Jails
  • Poudriere Ports Tree
  • Poudriere Packages to Build List
  • Poudriere Options
  • Nginx
  • Memcached
  • Ccache
  • Poudriere Packages Build Process
  • Our Repository Client Setup
  • Next Builds
  • Summary

There was as time when I had a dedicated script that would do just that – rebuild several ports as packages after the pkg upgrade cycle.

% cat pkg-recompile.sh
#! /bin/sh

# OPTIONS
  PORTS='audio/lame multimedia/ffmpeg sysutils/exfat-utils sysutils/fusefs-exfat'

# ONLY root CAN BUILD PACKAGES/PORTS
if [ "$( whoami )" != "root" ]
then
  echo "ER: only 'root' may use this script"
  exit 1
fi

# BUILD PACKAGES
case ${1} in
  # REBUILD PACKAGES
  (b|build)
    for PORT in ${PORTS}
    do
      pkg unlock -y ${PORT} 1> /dev/null 2> /dev/null
      env BATCH=yes DISABLE_VULNERABILITIES=yes \
        make -C /usr/ports/${PORT} build deinstall install clean &
      MAKE=${!}
      rctl -a process:${MAKE}:pcpu:deny=40
      wait ${MAKE}
      pkg lock -y ${PORT}
    done
    ;;

  # CLEAN
  (c|clean)
    for PORT in ${PORTS}
    do
      make -C /usr/ports/${PORT} clean
    done
    ;;

  # USAGE
  (*)
    echo "usage: ${0##*/} b|c|build|clean"
    exit 1
    ;;

esac

Now none of that is needed anymore … unless you want to Connect FreeBSD to FreeIPA/IDM server … this is the case where Poudriere comes pretty handy. You may configure/rebuild needed packages by hand or use a tool that will do that for you and you will then just use its custom build packages repository to install them on multiple systems. Scale often changes many things and this is not different with Poudriere tool.

Poudriere Name

… its quite unfortunate to say the least. I needed some time to actually learn to remember that name properly. Not sure I have any useful tips here – I just split it in half to make it easier to remember – as poud and riere parts. In the beginning I interpreted the pond part as British Pound … uncorrected of course. I really wish the author would name it simpler – like Rebuild or Bob the Builder for example πŸ™‚

So what does Poudriere really means? Its a French translation of Powder Keg – which means a place where gunpowder was stored. There is some logic in that … as all the power (gun power) is in the packages … and Poudriere creates that place.

UPDATE: Dan Langille just reminded me that Poudriere replaced Powder Keg which was a similar tool – that explains the French translation for the name πŸ™‚

Poudriere Features

The Poudriere is a bulk package builder and port tester. It uses a ‘clean’ FreeBSD Jails containers to build packages for defined FreeBSD version (supported or not) and a ‘snapshot’ of a FreeBSD Ports tree. Most of the time it will be the latest FreeBSD Ports tree ‘snapshot’ but nothing prevents you from using older ‘snapshots’ with older packages versions when needed.

Then the results (and logs) of these builds are available as HTML pages and you can (and probably should) host them as some WWW server.

All of this seems scary, complicated and pointless bloat to some … but it gets simple and obvious once you try it. You know me – I have an allergy for bullshit and bloat and Poudriere is really far from both of them.

Its kinda like with the famous UNIX co-creator Dennis Ritchie quote – “UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity.” – just kidding – Poudriere actually is quite simple once you start using it – and that is probably the biggest obstacle to knowing it better. Just start using it (in a VM or in a Jail) to get to know it better and once you know it better – setup it properly and just use. Its far from over-complicated solutions such as SELinux, systemd(1) or Kubernetes.

FreeBSD Host Setup

First things first. The ‘three kings’ of and FreeBSD system configuration:

  • /boot/loader.conf
  • /etc/rc.conf
  • /etc/sysctl.conf

Here they are:

The /boot/loader.conf file.

# cat /boot/loader.conf
security.bsd.allow_destructive_dtrace=0
kern.geom.label.disk_ident.enable=0
kern.geom.label.gptid.enable=0
cryptodev_load=YES
zfs_load=YES

The /etc/rc.conf file.

# cat /etc/rc.conf
  clear_tmp_enable=YES
  syslogd_flags="-ss"
  sendmail_enable=NONE
  hostname=fbsdpr
  ifconfig_em0="inet 10.0.10.123/24"
  defaultrouter="10.0.10.1"
  sshd_enable=YES
  dumpdev=AUTO
  zfs_enable=YES
  nginx_enable=YES
  memcached_enable=YES
  memcached_flags="-l localhost -m 8192"

The /etc/sysctl.conf file.

# cat /etc/sysctl.conf
vfs.zfs.min_auto_ashift=12

From the three above only the /etc/rc.conf is important as the other two only have settings from the bsdinstall(8) installer – as used with the Auto ZFS option.

We will also need to populate /etc/resolv.conf file to have DNS configured.

# echo nameserver 1.1.1.1 > /etc/resolv.conf

Pick your personal DNS server favorite here if the Cloudflare one does not suit your needs.

Poudriere Setup

First we need to install some packages – especially the Poudriere package – to make them more up-to-date we would prefer the latest branch of pkg(8) packages.

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

# grep latest /etc/pkg/FreeBSD.conf
  url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",

Now we can add needed packages.

# env ASSUME_ALWAYS_YES=yes \
    pkg install -y \
      poudriere \
      portmaster \
      screen \
      tmux \
      zsh \
      beadm \
      lsblk \
      nginx \
      git-lite \
      htop \
      tree \
      ccache-memcached \
      memcached \
      groff

Some of them are less needed but they definitely does not hurt for workflow. Absolute minimum are:

  • poudriere
  • nginx
  • git-lite
  • ccache-memcached
  • groff

Now … lets prepare some dirs and certs to make our packages signed.

# SSL=/usr/local/etc/ssl
# mkdir -p   ${SSL}/{keys,certs} /usr/ports/distfiles
# chmod 0600 ${SSL}/keys
# openssl genrsa -out ${SSL}/keys/poudriere.key 4096
# openssl rsa -in ${SSL}/keys/poudriere.key -pubout -out ${SSL}/certs/poudriere.cert

As we will be using ZFS for Poudriere we will now create dedicated dataset for it.

# zfs create -o mountpoint=/usr/local/poudriere zroot/poudriere

Now we will create the Poudriere config file.

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

Its quite basic – yet it will do the job.

Poudriere Jails

Next we will create Poudriere Jails for each FreeBSD version we want to create pkg(8) repositories with packages.

I will create Jails for all FreeBSD 13.x versions – supported or not.

# poudriere jail -c -j 13-2-R-amd64 -v 13.2-RELEASE
# poudriere jail -c -j 13-1-R-amd64 -v 13.1-RELEASE
# poudriere jail -c -j 13-0-R-amd64 -v 13.0-RELEASE -m ftp-archive

Keep in mind that you need to specify additional -m ftp-archive argument for unsupported FreeBSD versions.

After some time you will end up with ready to use Poudriere FreeBSD Jails containers as shown below.

# poudriere jail -l
13-0-R-amd64 13.0-RELEASE-p13 amd64 ftp-archive 2023-04-28 03:22:05 /usr/local/poudriere/jails/13-0-R-amd64
13-1-R-amd64 13.1-RELEASE-p7  amd64 http        2023-04-27 23:17:13 /usr/local/poudriere/jails/13-1-R-amd64
13-2-R-amd64 13.2-RELEASE     amd64 http        2023-04-27 23:15:30 /usr/local/poudriere/jails/13-2-R-amd64

Poudriere Ports Tree

You may already have an up-to-date FreeBSD Ports tree on your disk at usual /usr/ports location – but we need Poudriere to get its own one too.

# poudriere ports -c

After fetching one you can list it like that.

# poudriere ports -l
default   git+https 2023-04-27 06:16:42 /usr/local/poudriere/ports/default

Poudriere Packages to Build List

Here is the best part – you do not need to build all 33000+ ports – you may specify just several of them. This is what we would do now.

# cat << EOF > /usr/local/etc/poudriere.d/list
sysutils/beadm
sysutils/lsblk
devel/m4
EOF

Accepting all possible licenses is also a good idea.

# echo DISABLE_LICENSES=yes >> /usr/local/etc/poudriere.d/make.conf

We will also specify which options should (and should not) be included in our built packages.

# cat << EOF > /usr/local/etc/poudriere.d/13-0-R-amd64-make.conf
OPTIONS_UNSET+= DOCS NLS X11 EXAMPLES
ALLOW_UNSUPPORTED_SYSTEM=yes
DISABLE_LICENSES=yes
EOF

# cat << EOF > /usr/local/etc/poudriere.d/13-1-R-amd64-make.conf
OPTIONS_UNSET+= DOCS NLS X11 EXAMPLES
ALLOW_UNSUPPORTED_SYSTEM=yes
DISABLE_LICENSES=yes
EOF

# cat << EOF > /usr/local/etc/poudriere.d/13-2-R-amd64-make.conf
OPTIONS_UNSET+= DOCS NLS X11 EXAMPLES
ALLOW_UNSUPPORTED_SYSTEM=yes
DISABLE_LICENSES=yes
EOF

Poudriere Options

You may choose the Poudriere packages options the same interactive way you do when you use the FreeBSD Ports tree.

To do that – here are the needed spells.

# poudriere options -c -j 13-0-R-amd64 -f /usr/local/etc/poudriere.d/list
# poudriere options -c -j 13-1-R-amd64 -f /usr/local/etc/poudriere.d/list
# poudriere options -c -j 13-2-R-amd64 -f /usr/local/etc/poudriere.d/list

Nginx

To make most of the Poudriere you will also need some web server. I have chosen Nginx for that task as its currently ‘the’ standard for the Internet.

Its setup is not complicated – just repeat steps below and you are done.

# service nginx enable

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

# 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 ${IP};
    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

# service nginx restart

The /usr/local/etc/nginx/mime.types part will allow you to display the *.log files in the browser instead of ‘forcing’ the browser to pointlessly download them.

Our web server seems to work properly.

# sockstat -l4
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
www      nginx      95263 7  tcp4   *:80                  *:*
root     nginx      95262 7  tcp4   *:80                  *:*
root     sshd       706   5  tcp4   *:22                  *:*

Memcached

As we will be using devel/ccache-memcached package to speed up builds – we would also need memcached to be running.

We already have needed configuration in /etc/rc.conf file so we only need to start it.

# grep memcached /etc/rc.conf
  memcached_enable="YES"
  memcached_flags="-l localhost -m 8192"

# service memcached restart

# sockstat -l4
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
nobody   memcached  37844 13 tcp4   127.0.0.1:11211       *:*
www      nginx      69727 7  tcp4   *:80                  *:*
root     nginx      69726 7  tcp4   *:80                  *:*
root     sshd       706   5  tcp4   *:22                  *:*

Ccache

We will now configure ccache(1) service.

Like success have many father the same ccache(1) have many configs – to be sure – we will propagate all of them.

We will use /var/ccache dir for the ccache(1) cache dir = but feel free to put it somewhere else or even with a dedicated ZFS dataset.

# mkdir -p /var/ccache

# cat << EOF > /usr/local/etc/ccache.conf
max_size = 0
cache_dir = /var/ccache
base_dir = /var/ccache
memcached_conf = --SERVER=localhost:11211
memcached_only = true
EOF

# cat << EOF > /root/.ccache/ccache.conf
max_size = 0
cache_dir = /var/ccache
base_dir = /var/ccache
memcached_conf = --SERVER=localhost:11211
memcached_only = true
EOF

# cat << EOF > /var/ccache/ccache.conf
max_size = 0
cache_dir = /var/ccache
base_dir = /var/ccache
memcached_conf = --SERVER=localhost:11211
memcached_only = true
EOF

The ccache(1) stats output after several builds below.

# ccache -s
cache directory                     /var/ccache
primary config                      /var/ccache/ccache.conf
secondary config      (readonly)    /usr/local/etc/ccache.conf
stats updated                       Fri Apr 28 04:10:17 2023
cache hit (direct)                  4510
cache hit (preprocessed)             713
cache miss                          2481
cache hit rate                     67.80 %
called for link                     5616
called for preprocessing            1476
multiple source files                 18
compile failed                      1143
preprocessor error                   351
bad compiler arguments                72
unsupported source language            9
autoconf compile/link               3147
no input file                        441
cleanups performed                     0
files in cache                      6303
cache size                          26.6 MB

Poudriere Packages Build Process

Now as you have everything configured and ready – you may build your custom packages.

These next commands will build repositories with your configured packages.

# poudriere bulk -j 13-0-R-amd64 -f /usr/local/etc/poudriere.d/list
# poudriere bulk -j 13-1-R-amd64 -f /usr/local/etc/poudriere.d/list
# poudriere bulk -j 13-2-R-amd64 -f /usr/local/etc/poudriere.d/list

The Poudriere console output is pretty colorful and nice – here is how it looks.

poudriere-build

Lets check how it look on the browser side.

poudriere-www-01

Lets ‘click’ the 13-2-R-amd64-default name for some details.

poudriere-www-02

It shows that 14 packages has been built in the process and all of them succeed.

Lets now click the date_time build name.

poudriere-www-03

You will now see the details about that build run – with logs and time needed for each package build.

You can ‘click’ on the package name to get the build log details.

poudriere-www-04

Here is how our three repositories look after the build process.

# ls -l /usr/local/poudriere/data/packages
total 26K
drwxr-xr-x 4 root wheel 14 2023-04-28 04:10 13-0-R-amd64-default/
drwxr-xr-x 4 root wheel 14 2023-04-28 04:06 13-1-R-amd64-default/
drwxr-xr-x 4 root wheel 14 2023-04-28 04:07 13-2-R-amd64-default/

# tree /usr/local/poudriere/data/packages
/usr/local/poudriere/data/packages
β”œβ”€β”€ 13-0-R-amd64-default
β”‚Β Β  β”œβ”€β”€ All -> .latest/All
β”‚Β Β  β”œβ”€β”€ Latest -> .latest/Latest
β”‚Β Β  β”œβ”€β”€ meta.conf -> .latest/meta.conf
β”‚Β Β  β”œβ”€β”€ meta.pkg -> .latest/meta.pkg
β”‚Β Β  β”œβ”€β”€ meta.txz -> .latest/meta.txz
β”‚Β Β  β”œβ”€β”€ packagesite.pkg -> .latest/packagesite.pkg
β”‚Β Β  └── packagesite.txz -> .latest/packagesite.txz
β”œβ”€β”€ 13-1-R-amd64-default
β”‚Β Β  β”œβ”€β”€ All -> .latest/All
β”‚Β Β  β”œβ”€β”€ Latest -> .latest/Latest
β”‚Β Β  β”œβ”€β”€ meta.conf -> .latest/meta.conf
β”‚Β Β  β”œβ”€β”€ meta.pkg -> .latest/meta.pkg
β”‚Β Β  β”œβ”€β”€ meta.txz -> .latest/meta.txz
β”‚Β Β  β”œβ”€β”€ packagesite.pkg -> .latest/packagesite.pkg
β”‚Β Β  └── packagesite.txz -> .latest/packagesite.txz
└── 13-2-R-amd64-default
    β”œβ”€β”€ All -> .latest/All
    β”œβ”€β”€ Latest -> .latest/Latest
    β”œβ”€β”€ meta.conf -> .latest/meta.conf
    β”œβ”€β”€ meta.pkg -> .latest/meta.pkg
    β”œβ”€β”€ meta.txz -> .latest/meta.txz
    β”œβ”€β”€ packagesite.pkg -> .latest/packagesite.pkg
    └── packagesite.txz -> .latest/packagesite.txz

10 directories, 15 files

Our Repository Client Setup

Now we need to configure our FreeBSD clients to start using our Poudriere created repositories.

Here is what we need to do on such client.

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

# cat << EOF > /usr/local/etc/pkg/repos/13-2-R-amd64.conf
13-2-R-amd64: {
    url: "http:/10.0.10.123/packages/13-2-R-amd64-default/",
    mirror_type: "http",
    signature_type: "pubkey",
    pubkey: "/usr/local/etc/ssl/certs/poudriere.cert",
    enabled: yes,
    priority: 100
}
EOF

# pkg update -f
Updating FreeBSD repository catalogue...
Fetching meta.conf: 100%    163 B   0.2kB/s    00:01
Fetching packagesite.pkg: 100%    7 MiB 626.5kB/s    00:11
Processing entries: 100%
FreeBSD repository update completed. 32980 packages processed.
Updating 13-2-R-amd64-HEAD repository catalogue...
Fetching meta.conf: 100%    163 B   0.2kB/s    00:01
Fetching packagesite.pkg: 100%    6 KiB   5.7kB/s    00:01
Processing entries: 100%
13-2-R-amd64-HEAD repository update completed. 14 packages processed.
All repositories are up to date.

We now have our first FreeBSD client system configured against our Poudriere created repository.

Lets install/update the m4 package for a test.

# pkg install m4
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
Updating 13-2-R-amd64-HEAD repository catalogue...
13-2-R-amd64-HEAD 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:
        m4: 1.4.19,1 [13-2-R-amd64-HEAD]

Installed packages to be REINSTALLED:
        pkg-1.19.1_1 [13-2-R-amd64-HEAD] (options changed)

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

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

Proceed with this action? [y/N]: y
[1/2] Fetching pkg-1.19.1_1.pkg: 100%    8 MiB   8.7MB/s    00:01
[2/2] Fetching m4-1.4.19,1.pkg: 100%  214 KiB 218.7kB/s    00:01
Checking integrity... done (0 conflicting)
[1/2] Reinstalling pkg-1.19.1_1...
[1/2] Extracting pkg-1.19.1_1: 100%
[2/2] Installing m4-1.4.19,1...
[2/2] Extracting m4-1.4.19,1: 100%

Now some FreeBSD client notes … if you are a Linux fan you probably know that – for example on Red Hat Linux (and its clones) – its relatively easy to just list the configured repositories with yum repolist command.

# yum repolist
repo id         repo name
appstream       CentOS Linux 8 - AppStream
baseos          CentOS Linux 8 - BaseOS
epel            Extra Packages for Enterprise Linux 8 - x86_64
epel-modular    Extra Packages for Enterprise Linux Modular 8 - x86_64
extras          CentOS Linux 8 - Extras

… unfortunately there is not 1:1 equivalent on FreeBSD side for pkg(8) repositories.

The closest one that is available out of the box are:

# pkg -vv | grep -A 999 '^Repositories:'
Repositories:
  FreeBSD: {
    url             : "pkg+http://pkg.FreeBSD.org/FreeBSD:13:amd64/latest",
    enabled         : yes,
    priority        : 0,
    mirror_type     : "SRV",
    signature_type  : "FINGERPRINTS",
    fingerprints    : "/usr/share/keys/pkg"
  }
  13-2-R-amd64: {
    url             : "http://10.0.10.123/packages/13-2-R-amd64-default/",
    enabled         : yes,
    priority        : 100,
    mirror_type     : "HTTP",
    signature_type  : "PUBKEY",
    pubkey          : "/usr/local/etc/ssl/certs/poudriere.cert"
  }

# grep -h '^[^#]' /etc/pkg/* /usr/local/etc/pkg/repos/*
FreeBSD: {
  url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
13-2-R-amd64: {
    url: "http://10.0.10.123/packages/13-2-R-amd64-default/",
    mirror_type: "http",
    signature_type: "pubkey",
    pubkey: "/usr/local/etc/ssl/certs/poudriere.cert",
    enabled: yes,
    priority: 100
}

Not very pretty.

After asking at GitHub for potential solution or pkg(8)man page overlook I was informed that there is no such option … so I came with my own POSIX /bin/sh shell scripts/functions for the rescue πŸ™‚

For example pkg-repo-var-en.sh that will list all pkg(8) repositories with their enabled/disabled status.

# ./pkg-repo-var-en.sh
REPO          ENABLED  PRIO  URL
FreeBSD       yes      0     pkg+http://pkg.FreeBSD.org/${ABI}/latest
13-2-R-amd64  yes      100   http://10.0.10.123/packages/13-2-R-amd64

# cat pkg-repo-var-en.sh
#! /bin/sh

( # HEADER
  echo -e "\nREPO ENABLED PRIO URL"
  for REPO in /etc/pkg/* /usr/local/etc/pkg/repos/*
  do
    REPOCUR=$( grep '^[^#]' "${REPO}" )

    # REPO
    echo "${REPOCUR}" | awk -F ':' '/\{[\ \t]*$/ {printf(" %s ",$1)}'

    # ENABLED
    echo "${REPOCUR}" | awk '/enabled:/ {printf(" %s ",$NF)}' | tr -cd '[a-zA-Z ]'

    # PRIO
    if echo "${REPOCUR}" | grep -q priority
    then
      echo "${REPOCUR}" | awk '/priority:/ {printf(" %s ",$NF)}' | tr -cd '[0-9 ]'
    else
      echo -n " 0 "
    fi

    # URL
    echo "${REPOCUR}" | grep '^[^#]' | awk -F'"' '/url:/ {print $2}' | tr -d ','

  done 2> /dev/null
) | column -t 2> /dev/null

Next Builds

So … you have successfully build your custom repository once … these are the steps to create new up-to-date package every next time.

// UPDATE JAILS
# poudriere jail -u -j 13-0-R-amd64
# poudriere jail -u -j 13-1-R-amd64
# poudriere jail -u -j 13-2-R-amd64

// UPDATE PORTS
# poudriere ports -u

// BUILD REPOSITORIES
# poudriere bulk -j 13-0-R-amd64 -f /usr/local/etc/poudriere.d/list
# poudriere bulk -j 13-1-R-amd64 -f /usr/local/etc/poudriere.d/list
# poudriere bulk -j 13-2-R-amd64 -f /usr/local/etc/poudriere.d/list

For example – if there are not new packages/changes – this is how the Poudriere output would look like.

poudriere-build-not-needed

Summary

Not sure what should I add here more … I definitely need to compare Poudriere against ports-mgmt/synth alternative one day … but it is not this day – as Aragorn once said πŸ™‚

Pick your packages to customize and have fun.

Take care.

Silent Fanless Dell Wyse 3030 LT FreeBSD Server

Why use quite outdated (released in 2016) Dell Wyse 3030 LT terminal under FreeBSD? There are probably many answers to that question. I recently started to use these for my backup purposes … and to be honest I am really pleased with them.

dell-wyse-3030

In the past I used to make my own boxes based on Mini ITX motherboards such as these:

… and to be honest – I was pretty pleased with their service. The reason that I started to look for alternative and settled on Dell Wyse 3030 LT terminals were Pico ITX power supplies. Both of them failed somewhere between now and 2018. I got replacements from China but then these boxes (without any active cooling) started to overheat. I also tried to replace motherboards with other ones – but still had the same problem. I really wanted to avoid active cooling because it creates a lot of pointless dust. Both inside and outside the case.

My current point of view is that these used Dell Wyse 3030 LT terminals are both cheaper at buy and later at usage costs as they draw a lot less power then the Mini ITX motherboard based ones.

Dell Wyse 3030 LT

The Dell Wyse 3030 LT terminals are not that much powerful – they should be treated as Raspberry Pi boards more then like a casual mini PC. Both because of their power draw and compute power. Here is how such Dell Wyse 3030 LT terminal looks like. I put a 2.5 USB attached hard disk on top of it – its WD Elements with 5 TB capacity. The USB pendrive that is plugged into one of the front USB ports is Lexar S47 32GB USB drive. This is where FreeBSD 13.2-RC6 is installed. I will of course update it when 13.2-RELEASE is ready to rumble.

dell-3030-wd

You may ask why WD Elements and its a good question. The answer is I do not care. I just sort the drives for ‘best price’ order and buy the cheapest one. The other Dell Wyse 3030 LT terminal I got has Seagate Basic Portable 2.5 USB drive instead – also 5 TB in capacity. Works the same well. Cost almost the same. I do not remember which one was better deal but they both were very close.

dell-3030-seagate

Ports

The Dell Wyse 3030 LT terminal has quite a few useful ports that most of them I find useful.

dell-wyse-3030-lt-ports

These are:

  • (1) — 1 x USB 3.0 (front)
  • (2) — 2 x USB 2.0 (front)
  • (3) — 1 x Mini Jack (front)
  • (4) — 1 x LAN 10/100/1000 Realtek RTL8111/8168/8411 (back)
  • (5) — 2 x DisplayPort (back)
  • (6) — 1 x USB 2.0 (back)
  • (*) — 1 x WLAN Intel AC-7265 (internal)

The hardware specs are not that great for today’s standards.

MODEL: Dell Wyse 3030 LT
  CPU: Intel Celeron N2807 2 x 1.58 GHz (2.16 GHz Turbo)
  RAM: 2 GB DDR3L (soldered on motherboard)
 eMMC: 4 GB Flash (soldered on motherboard)
 mPCI: Intel Dual Band Wireless-AC 7265

I use ZFS filesystem for my data and one may say that 2 GB RAM is not enough for ZFS needs … but OpenZFS page recommends 2 GB RAM as a minimum so I do not have to worry here.

Have enough memory: A minimum of 2GB of memory is recommended for ZFS. Additional memory is strongly recommended when the compression and deduplication features are enabled.

The source of that information comes from OpenZFS FAQ page.

In the past I have successfully run a 512 MB box with 2 x 2 TB ZFS mirror for several years. I have had zero crashes/panics/problems with it. Everything just worked like it suppose to. I also run several simple services on the same 512 MB box – like NFS and SAMBA services to export the available data to machines on the local network. The only thing I did back then was to limit the ARC usage up to 128 MB of RAM. Nothing more.

With current 2 GB RAM that I have configured ARC to be 128-256 MB with following settings in the /etc/sysctl.conf file.

# ZFS ARC
# ZFS TUNING
  vfs.zfs.arc.min=134217728
  vfs.zfs.arc.max=268435456

The details about that Intel Celeron N2807 CPU can be found on Intel ARK database.

Here are its specs. The most interesting ones are TDP(W).

N2807

The lscpu(1) shows following information about it.

wyse3030 % lscpu
Architecture:            amd64
Byte Order:              Little Endian
Total CPU(s):            2
Thread(s) per core:      1
Core(s) per socket:      2
Socket(s):               1
Vendor:                  GenuineIntel
CPU family:              6
Model:                   55
Model name:              Intel(R) Celeron(R) CPU  N2807  @ 1.58GHz
Stepping:                8
L1d cache:               24K
L1i cache:               32K
L2 cache:                1024K
Flags:                   fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 cflsh ds acpi mmx fxsr sse sse2 ss htt tm pbe sse3 pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 movbe popcnt tsc_deadline rdrnd tsc_adjust smep erms fpcsds syscall nx rdtscp lm lahf_lm

The FreeBSD information about it from /var/run/dmesg.boot looks as follows.

CPU: Intel(R) Celeron(R) CPU  N2807  @ 1.58GHz (1583.40-MHz K8-class CPU)
  Origin="GenuineIntel"  Id=0x30678  Family=0x6  Model=0x37  Stepping=8
  Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE>
  Features2=0x41d8e3bf<SSE3,PCLMULQDQ,DTES64,MON,DS_CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,MOVBE,POPCNT,TSCDLT,RDRAND>
  AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
  AMD Features2=0x101<LAHF,Prefetch>
  Structured Extended Features=0x2282<TSCADJ,SMEP,ERMS,NFPUSG>
  VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID
  TSC: P-state invariant, performance statistics

Several C-states and P-states are properly supported on FreeBSD as shown below.

wyse3030 % sysctl dev.cpu.0
dev.cpu.0.temperature: 44.0C
dev.cpu.0.coretemp.throttle_log: 0
dev.cpu.0.coretemp.tjmax: 100.0C
dev.cpu.0.coretemp.resolution: 1
dev.cpu.0.coretemp.delta: 56
dev.cpu.0.cx_method: C1/hlt C2/io
dev.cpu.0.cx_usage_counters: 21488971 0
dev.cpu.0.cx_usage: 100.00% 0.00% last 409us
dev.cpu.0.cx_lowest: C1
dev.cpu.0.cx_supported: C1/1/1 C2/3/104
dev.cpu.0.freq_levels: 2501/45000 2500/45000 2000/33977 1800/29872 1600/25926 1400/22148 1200/18525 1000/15060 800/11752
dev.cpu.0.freq: 1400
dev.cpu.0.%parent: acpi0
dev.cpu.0.%pnpinfo: _HID=none _UID=0 _CID=none
dev.cpu.0.%location: handle=\_PR_.CPU0
dev.cpu.0.%driver: cpu
dev.cpu.0.%desc: ACPI CPU

Keep in mind to load coretemp(4) module at system startup to get all needed information.

The output from sensors.sh is available below.

wyse3030 # sensors.sh

            BATTERY/AC/TIME/FAN/SPEED
------------------------------------
               dev.cpu.0.cx_supported: C1/1/1 C2/2/500 C3/3/1500
                   dev.cpu.0.cx_usage: 26.04% 12.27% 61.68% last 125us
                       dev.cpu.0.freq: 498
                hw.acpi.cpu.cx_lowest: C8
                            powerd(8): running

                  SYSTEM/TEMPERATURES
------------------------------------
                dev.cpu.0.temperature: 37.0C (max: 105.0C)
                dev.cpu.1.temperature: 40.0C (max: 105.0C)
      hw.acpi.thermal.tz0.temperature: 26.9C (max: 90.1C)

                   DISKS/TEMPERATURES
------------------------------------
        smart.da1.temperature_celsius: 37.0C

The biggest drawback is the lack of support for aesni(4) acceleration. Test I had made – with powerd(8) enabled – shows that its able to reach 15-16 MB/s of speed with calculating that encryption on these two cores. Its more then enough for my needs as I rarely go above 10-11 MB/s on the WiFi transfers.

If you are interested how the internals of Dell Wyse 3030 LT motherboard looks like – take a journey to David Parkinson page at Dell Wyse 3030 LT location. You will also find a lot information about other Thin Client software – often also called Terminals.

I did not bothered to unscrew mine knowing what David Parkinson shows on his site.

WiFi

As the Dell Wyse 3030 LT has the Intel Dual Band Wireless-AC 7265 WiFi card from 2014 – almost a decade old WiFi card – there is a big chance that FreeBSD will flawlessly support it and at least allow 802.11n protocol and speed – as its 9 years old.

Here are some specs from Intel on that WiFi card.

AC7265

… and here is the neat part πŸ˜€ – it does not work on FreeBSD – its not able to connect to WiFi access point – what were you thinking πŸ™‚

This is what I tried at both 2.4GHz and 5.0GHz WiFi networks that are WPA2 protected.

wyse3030 # grep iwm /var/run/dmesg.boot 
iwm0: <Intel(R) Dual Band Wireless AC 7265> mem 0x88500000-0x88501fff at device 0.0 on pci2
iwm0: hw rev 0x210, fw ver 22.361476.0, address d0:57:7b:13:41:4c

wyse3030 # pciconf -lv iwm0
iwm0@pci0:2:0:0: class=0x028000 rev=0x59 hdr=0x00 vendor=0x8086 device=0x095a subvendor=0x8086 subdevice=0x5410
vendor = 'Intel Corporation'
device = 'Wireless 7265'
class = network

wyse3030 #
sysctl -n net.wlan.devices iwm0
wyse3030 #
ifconfig wlan0 create wlandev $( !! )
wyse3030 #
ifconfig wlan0 up
wyse3030 #
ifconfig wlan0 scan SSID/MESH ID BSSID CHAN RATE S:N INT CAPS wifinet d8:07:b6:aa:bb:00 7 54M -63:-96 100 EP APCHANREP WPA RSN BSSLOAD HTCAP VHTCAP VHTOPMODE
wifinet d8:07:b6:aa:bb:02 40 54M -80:-96 100 EP VHTPWRENV APCHANREP WPA RSN HTCAP VHTCAP

These are my WiFi networks that I will try to use:

  • WiFi 2.4GHz – wifinetd8:07:b6:aa:bb:00
  • WiFi 5.0GHz – wifinetd8:07:b6:aa:bb:02

Results below.

WiFi 2.4GHz

wyse3030 # wpa_supplicant -i wlan0 -c /etc/wpa_supplicant.conf
Successfully initialized wpa_supplicant
ioctl[SIOCS80211, op=20, val=0, arg_len=7]: Invalid argument
ioctl[SIOCS80211, op=20, val=0, arg_len=7]: Invalid argument
ioctl[SIOCS80211, op=103, val=0, arg_len=128]: Operation now in progress
wlan0: CTRL-EVENT-SCAN-FAILED ret=-1 retry=1
wlan0: Trying to associate with d8:07:b6:aa:bb:00 (SSID='wifinet' freq=2442 MHz)
wlan0: Authentication with d8:07:b6:aa:bb:00 timed out.
wlan0: CTRL-EVENT-DISCONNECTED bssid=d8:07:b6:aa:bb:00 reason=3 locally_generated=1
BSSID d8:07:b6:aa:bb:00 ignore list count incremented to 2, ignoring for 10 seconds
wlan0: CTRL-EVENT-DSCP-POLICY clear_all
wlan0: Trying to associate with d8:07:b6:aa:bb:00 (SSID='wifinet' freq=2442 MHz)
wlan0: Authentication with d8:07:b6:aa:bb:00 timed out.
wlan0: CTRL-EVENT-DISCONNECTED bssid=d8:07:b6:aa:bb:00 reason=3 locally_generated=1
BSSID d8:07:b6:aa:bb:00 ignore list count incremented to 2, ignoring for 10 seconds
wlan0: CTRL-EVENT-DSCP-POLICY clear_all
wlan0: Trying to associate with d8:07:b6:aa:bb:00 (SSID='wifinet' freq=2442 MHz)
wlan0: Authentication with d8:07:b6:aa:bb:00 timed out.
wlan0: CTRL-EVENT-DISCONNECTED bssid=d8:07:b6:aa:bb:00 reason=3 locally_generated=1
BSSID d8:07:b6:aa:bb:00 ignore list count incremented to 2, ignoring for 10 seconds
wlan0: CTRL-EVENT-DSCP-POLICY clear_all
wlan0: Trying to associate with d8:07:b6:aa:bb:00 (SSID='wifinet' freq=2442 MHz)
^C

WiFi 5.0GHz

wyse3030 # wpa_supplicant -i wlan0 -c /etc/wpa_supplicant.conf
Successfully initialized wpa_supplicant
ioctl[SIOCS80211, op=20, val=0, arg_len=7]: Invalid argument
ioctl[SIOCS80211, op=20, val=0, arg_len=7]: Invalid argument
wlan0: Trying to associate with d8:07:b6:aa:bb:02 (SSID='wifinet' freq=5200 MHz)
wlan0: Authentication with d8:07:b6:aa:bb:02 timed out.
wlan0: CTRL-EVENT-DISCONNECTED bssid=d8:07:b6:aa:bb:02 reason=3 locally_generated=1
BSSID d8:07:b6:aa:bb:02 ignore list count incremented to 2, ignoring for 10 seconds
wlan0: CTRL-EVENT-DSCP-POLICY clear_all
wlan0: Trying to associate with d8:07:b6:aa:bb:02 (SSID='wifinet' freq=5200 MHz)
wlan0: Authentication with d8:07:b6:aa:bb:02 timed out.
wlan0: CTRL-EVENT-DISCONNECTED bssid=d8:07:b6:aa:bb:02 reason=3 locally_generated=1
BSSID d8:07:b6:aa:bb:02 ignore list count incremented to 2, ignoring for 10 seconds
wlan0: CTRL-EVENT-DSCP-POLICY clear_all
wlan0: Trying to associate with d8:07:b6:aa:bb:02 (SSID='wifinet' freq=5200 MHz)
wlan0: Authentication with d8:07:b6:aa:bb:02 timed out.
wlan0: CTRL-EVENT-DISCONNECTED bssid=d8:07:b6:aa:bb:02 reason=3 locally_generated=1
BSSID d8:07:b6:aa:bb:02 ignore list count incremented to 2, ignoring for 10 seconds
wlan0: CTRL-EVENT-DSCP-POLICY clear_all
wlan0: Trying to associate with d8:07:b6:aa:bb:02 (SSID='wifinet' freq=5200 MHz)
wlan0: Authentication with d8:07:b6:aa:bb:02 timed out.
wlan0: CTRL-EVENT-DISCONNECTED bssid=d8:07:b6:aa:bb:02 reason=3 locally_generated=1
BSSID d8:07:b6:aa:bb:02 ignore list count incremented to 2, ignoring for 10 seconds
wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=0 ssid="wifinet" auth_failures=1 duration=10 reason=CONN_FAILED
wlan0: CTRL-EVENT-DSCP-POLICY clear_all
wlan0: CTRL-EVENT-SSID-REENABLED id=0 ssid="wifinet"
wlan0: Trying to associate with d8:07:b6:aa:bb:02 (SSID='wifinet' freq=5200 MHz)
wlan0: CTRL-EVENT-DISCONNECTED bssid=d8:07:b6:aa:bb:02 reason=3 locally_generated=1
wlan0: CTRL-EVENT-DSCP-POLICY clear_all
wlan0: CTRL-EVENT-DSCP-POLICY clear_all
wlan0: CTRL-EVENT-TERMINATING 
^C

… and to be fair – I have used latest and greatest FreeBSD 13.2-RC6 (the 13.2-RELEASE is probably available now). I even installed the comms/iwmbt-firmware package hoping it would solve anything – it does not change anything.

For the record – this is how properly working WiFi connection looks like on FreeBSD.

# ifconfig wlan0 up 
# wpa_supplicant -i wlan0 -c /etc/wpa_supplicant.conf
Successfully initialized wpa_supplicant
ioctl[SIOCS80211, op=20, val=0, arg_len=7]: Invalid argument
ioctl[SIOCS80211, op=20, val=0, arg_len=7]: Invalid argument
wlan0: Trying to associate with d8:07:b6:aa:bb:00 (SSID='wifinet' freq=2442 MHz)
wlan0: Associated with d8:07:b6:aa:bb:00
wlan0: WPA: Key negotiation completed with d8:07:b6:aa:bb:00 [PTK=CCMP GTK=CCMP]
wlan0: CTRL-EVENT-CONNECTED - Connection to d8:07:b6:aa:bb:00 completed [id=43 id_str=]

At this point (after you get the CTRL-EVENT-CONNECTED message) you hit [CTRL]+[Z] then type bg at the prompt to keep wpa_supplicant(8) process in the background – and then dhclient wlan0 to get the IP address, default gateway and DNS servers.

The best FreeBSD can get on that box when it comes to WiFi side is Realtek RTL8188CUS tiny USB dongle … but while its 802.11n capable – the FreeBSD is only able to support 802.11g speeds on it. Details here – Realtek RTL8188CUS – USB 802.11n WiFi Review – in one of my older articles.

You now probably understand why I have these two WiFi antennas detached πŸ™‚ – but for the record – I have tested the WiFi connection with both antennas attached to that Intel AC 7265 card.

LAN

While WiFi on FreeBSD sucks greatly the builtin LAN – Realtek RTL8111/8168/8411 – works quite well with re(4) driver … but it needs one spacial quirk to work πŸ™‚

All network connections need to be restarted at the end of the boot process to work – if you do not do that – you just do not have network connectivity at all – I was not able to track why its fucked up like that – so I went with the idea to use /etc/rc.local scripts as its already there and its really late in the boot process. Here are mine /etc/rc.local script contents that seem to workaround that fuckup well.

wyse3030 % cat /etc/rc.local
#! /bin/sh

# RESTART NETWORKING
  (
  service netif   restart 1> /dev/null 2> /dev/null
  service routing restart 1> /dev/null 2> /dev/null
  ) &

To not waste time I put both netif and routing services in the background for startup.

DisplayPort

The DisplayPort sockets just work – when attached to the 1080p monitor they just deliver. I tried only in the vt(4) console mode. I did not tried X11 mode – but I suspect that the CPU is so old that it will work flawlessly with i915kms.ko driver from graphics/drm-fbsd13-kmod package.

When it comes to early booting – set your native screen resolution in the /boot/loader.conf file as specified below.

# CONSOLE RESOLUTION # --------------------------------------------------------
  kern.vt.fb.default.mode=1920x1080    # FORCE FHD
  efi_max_resolution=1920x1080         # FORCE FHD

Also – if you (like me) like to have small/smaller font size in the terminal – this will also be helpful in the /boot/loader.conf file.

  screen.font=6x12          # USE SMALLEST FONT NO MATTER THE RESOLUTION

USB

The USB ports work as desired. Both USB 2.0 and USB 3.0 ports work without any issues.

I currently use Lexar S47 32 GB USB tiny dongle foe FreeBSD system. I did not yet tested the builtin eMMC 4 GB flash storage space – will probably add some UPDATE about it in the future.

Data

Lets get back to the main responsibility of that box – backups. In the past my main NAS system used to have two 5 TB disks in ZFS mirror – but as I have another offsite copy and another offline copy and I also have my main copy always with me – I now find it pointless to have this single NAS mirrored. Besides – its more then 3-2-1 backup rule anyway …

As this box has 4 USB ports one can of course even create raidz ZFS pool with 3 drives for data and 1 for parity. Nothing stops you from doing that. You will get 15 TB of usable storage that way … not sure how log would it take to rebuild through. As these are SMR drives you may consider raidz2 or mirror instead. I also have some tips for ZFS on SMR Drives here.

Costs

This is the neat part … and I am not joking here. My earlier setups cost about $110 to $120 only for the case/motherboard/PSUs/RAM/etc. You needed to add disk costs to that on top. But not with this one. I got several of these Dell Wyse 3030 LT terminals for less then $18 each … and it was not a one time offer – they just cost that much now.

The disks (5 TB 2.5 USB drives) that I use also got cheaper in time and its relatively easy to get a used one for about $80. Does not matter if its Seagate or Western Digital or whatever. They are very similar cheap 5400 rpm SMR drives.

This make my new backup solution cost about $100 for a 5 TB space of storage.

Configuration

This is the main FreeBSD config /etc/rc.conf file.

wyse3030 % cat /etc/rc.conf
# BOOT/SILENCE # -------------------------------------------------------------
  rc_startmsgs=NO
  rc_info=NO

# NETWORK # ------------------------------------------------------------------
  hostname=wyse3030
  ifconfig_re0="inet 10.0.0.2/24"
  defaultrouter="10.0.0.1"
  defaultroute_delay=3
  defaultroute_carrier_delay=3
  gateway_enable=YES

# MODULES/COMMON/BASE # ------------------------------------------------------
  kld_list="${kld_list} fusefs coretemp sem cpuctl ichsmb"

# POWER # --------------------------------------------------------------------
  performance_cx_lowest=Cmax
  economy_cx_lowest=Cmax
  powerd_enable=YES
  powerd_flags="-n adaptive -a hiadaptive -b adaptive -m 100 -M 2000"

# DAEMONS # ------------------------------------------------------------------
  syslogd_flags="-ss"
  sshd_enable=YES
  zfs_enable=YES
  sendmail_enable=NO
  sendmail_submit_enable=YES
  sendmail_outbound_enable=NO
  sendmail_msp_queue_enable=NO

# OTHER # --------------------------------------------------------------------
  keyrate=fast
  virecover_enable=NO
  update_motd=NO
  hostid_enable=NO
  entropy_file=NO
  savecore_enable=NO
  clear_tmp_enable=YES
  dumpdev=AUTO

Options that can be changed anytime at /etc/sysctl.conf file below.

wyse3030 % cat /etc/sysctl.conf
# SECURITY # ------------------------------------------------------------------
  security.bsd.see_jail_proc=0
  security.bsd.unprivileged_proc_debug=0

# SECURITY/RANDOM PID # -------------------------------------------------------
  kern.randompid=1

# ANNOYING THINGS # -----------------------------------------------------------
  vfs.usermount=1
  kern.coredump=0
  hw.syscons.bell=0
  kern.vt.enable_bell=0

# ZFS ASHIFT 4k BLOCK SIZE # --------------------------------------------------
  vfs.zfs.min_auto_ashift=12

# ZFS DELETE FUCKUP TRIM # ----------------------------------------------------
  vfs.zfs.vdev.trim_max_active=1

# ZFS ARC 128MB FORCE # -------------------------------------------------------
  vfs.zfs.arc.min=134217728
  vfs.zfs.arc.max=268435456

# JAILS/ALLOW UPGRADES IN JAILS # ---------------------------------------------
  security.jail.chflags_allowed=1

# JAILS/ALLOW RAW SOCKETS # ---------------------------------------------------
  security.jail.allow_raw_sockets=1

# ALLOW idprio(8) USE BY REGULAR USER # ---------------------------------------
  security.bsd.unprivileged_idprio=1

… and last but not least (actually first :> to be read) the /boot/loader.conf file.

wyse3030 % cat /boot/loader.conf
# CONSOLE COMMON # ------------------------------------------------------------
  autoboot_delay=2          # USE '-1' => NO WAIT | USE 'NO' => INFINITE WAIT
  loader_logo=none          # LOGO POSIBILITES: fbsdbw beastiebw beastie none
  loader_menu_frame=none    # REMOVE FRAMES FROM FreeBSD BOOT MENU
  screen.font=6x12          # USE SMALLEST FONT NO MATTER THE RESOLUTION

# CONSOLE RESOLUTION # --------------------------------------------------------
  kern.vt.fb.default.mode=1920x1080    # FORCE FHD
  efi_max_resolution=1920x1080         # FORCE FHD

# MODULES # -------------------------------------------------------------------
  geom_eli_load=YES
  cryptodev_load=YES
  zfs_load=YES

# DISABLE /dev/diskid/* AND /dev/gptid/* ENTRIES FOR DISKS # ------------------
  kern.geom.label.disk_ident.enable=0
  kern.geom.label.gptid.enable=0

# COLORS # --------------------------------------------------------------------
  kern.vt.color.0.rgb="#000000"
  kern.vt.color.1.rgb="#dc322f"
  kern.vt.color.2.rgb="#859900"
  kern.vt.color.3.rgb="#b58900"
  kern.vt.color.4.rgb="#268bd2"
  kern.vt.color.5.rgb="#ec0048"
  kern.vt.color.6.rgb="#2aa198"
  kern.vt.color.7.rgb="#94a3a5"
  kern.vt.color.8.rgb="#586e75"
  kern.vt.color.9.rgb="#cb4b16"
  kern.vt.color.10.rgb="#859900"
  kern.vt.color.11.rgb="#b58900"
  kern.vt.color.12.rgb="#268bd2"
  kern.vt.color.13.rgb="#d33682"
  kern.vt.color.14.rgb="#2aa198"
  kern.vt.color.15.rgb="#6c71c4"

# RACCT/RCTL RESOURCE LIMITS # ------------------------------------------------
  kern.racct.enable=1

# ZFS TUNING # ----------------------------------------------------------------
  vfs.zfs.prefetch_disable=1

# POWER MANAGEMENT POWER OFF DEVICES WITHOUT ATTACHED DRIVER # ----------------
  hw.pci.do_power_nodriver=3

# POWER MANAGEMENT FOR EVERY USED AHCI CHANNEL (ahcich 0-7) # -----------------
  hint.ahcich.0.pm_level=5
  hint.ahcich.1.pm_level=5
  hint.ahcich.2.pm_level=5
  hint.ahcich.3.pm_level=5
  hint.ahcich.4.pm_level=5
  hint.ahcich.5.pm_level=5
  hint.ahcich.6.pm_level=5
  hint.ahcich.7.pm_level=5

# DISABLE DESTRUCTIVE DTrace # ------------------------------------------------
  security.bsd.allow_destructive_dtrace=0

There is also this 5 TB disk drive configuration to be mentioned.

wyse3030 # gpart destroy -F da0
wyse3030 # dd if=/dev/zero of=/dev/da0 bs=1m status=progress count=10
wyse3030 # gpart create -s GPT da0
wyse3030 # gpart add -t freebsd-zfs -a 4k da0
wyse3030 # geli init -s 4096 da0p1
wyse3030 # geli attach da0p1

Why I use password based encryption and not based on key? If someone would steal that device then with attached key on – for example – USB drive – all the data would be accessible – and all encryption and effort would be lost. With password based encryption whoever steals the devices gets some nice /dev/random input from my disk because its encrypted.

In the end these boxes do not hang by themselves and when there is power outage – its not that common like twice a week. Its more like once a quarter – I do not mind typing my password once in a quarter to make my data safe from people that should not be allowed to access it.

ZFS Pool Configuration

I did not used anything spectacular for ZFS configuration – just disabled atime and enabled compression that would save some space. I also increased the recordsize to 1M so the compressratio would be a little better … but nothing more to be honest.

wyse3030 # zpool history wd
History for 'wd':
2023-04-05.14:46:01 zpool create wd /dev/da0p1.eli
2023-04-05.14:46:07 zfs set compression=zstd wd
2023-04-05.14:46:12 zfs set atime=off wd
2023-04-05.14:46:15 zfs set recordsize=1m wd
2023-04-05.14:51:46 zfs create wd/data
2023-04-05.14:51:50 zfs set mountpoint=none wd
2023-04-05.14:52:00 zfs set mountpoint=/data wd/data

As you probably guessed the wd name is for the Western Digital 5 TB drive. If you are curious (and you probably are) the second ZFS pool is called seagate πŸ™‚

Last time I used the LZ4 compression for the ZFS pool. Not I use the ZSTD compression and the compressratio improved from 1.04 to 1.07 – almost twice more efficient.

wyse3030 % zfs get compressratio
NAME                                      PROPERTY       VALUE  SOURCE
wd                                        compressratio  1.07x  -
wd/data                                   compressratio  1.07x  -

One may think that 7% of more data space is almost ‘non-existent’ – think again. When it comes to terabytes it makes a big difference. In my case when my real data takes 4.2 TB and compressed one takes 3.9 TB its … 245 GB of space. For free. Thank you ZFS.

Quirks

The ‘quirks’ are things that need to be done differently then usual to make the device ‘happy’ – to make it work the way we want.

One of the Dell Wyse 3030 LT quirks is its bot process … it does not need any additional configuration – I just want to mention it – so you will not be stressed about it. After the FreeBSD loader(8) menu there is slight pause before continuing into the ‘rest’ of the boot process. Its several seconds long and its harmless. Here is how it looks on attached screen.

freebsd-bootloader

Power Usage Comparison

So its dirt cheap … and takes HALF of the power then my previews Mini ITX solution. The Mini ITX based systems used about 10.4 W of power when at idle state.

After measuring the Dell Wyse 3030 LT terminal power consumption with a kill-a-watt physical device – its only about 4.5 W only … and this is with % TB of 2.5 disk attached at idle state.

Another interesting fact is that I used the same ‘external’ power supply that I used for these Mini ITX boxes.

power-supply

Its 2.5A at 12V (which means 30 W)- exactly what a Dell Wyse 3030 LT terminal needs – according to its specification. As you can see from the photo above – the official power supply – while quite similar in size – needs a lot more space because of the additional 3-pin power cord – which is quite thick and takes a lot more space.

As in the past – I used python(1) [1] processes to load the CPU and dd(8) commands to load the drives I/O subsystem.

[1] # echo '999999999999999999 ** 999999999999999999' | python
[2] # dd if=/dev/da0  of=/dev/null  bs=1M
[3] # dd if=/dev/zero of=/data/FILE bs=1M

I will also include older Mini ITX based system measurements.

BOX        POWER  CPU          I/O
Wyse3030   3.8 W  IDLE         IDLE
MiniITX   10.5 W  IDLE         IDLE


BOX        POWER  CPU          I/O
Wyse3030  10.3 W  8 Thread(s)  3 DISK READ Thread(s) + 3 DISK WRITE Thread(s)
MiniITX   17.8 W  8 Thread(s)  3 DISK READ Thread(s) + 3 DISK WRITE Thread(s)

So after cutting CAPEX costs from about $110 to $15 I also lowered the OPEX price in half.

What can I say … I really appreciate and like the price/performance ratio πŸ™‚

Cloud Storage Costs Comparison

I am not a fan of cloud based storage – its just damn overpriced to say the least.

In the past I have made multiple calculations about cloud storage costs and it will be no different this time. We need to assume some cost of 1kWh of power. In Poland its about $0.25 for 1kWh which means running a device that draws 1000 Watts for entire hour.

Assuming that our Dell Wyse 3030 LT uses about 4.5W all the time it would make the following costs.

  COST  TIME 
 $0.03  1 DAY(s)
 $9.96  1 YEAR(s)
$29.88  3 YEAR(s)
$49.80  5 YEAR(s)

Combining that with server cost ($100) we get TCO for our self hosted 5TB storage service.

COST  TIME
$110  1 YEAR(s)
$130  3 YEAR(s)
$150  5 YEAR(s)

This time after searching for cheapest cloud based storage I found these services.

  • Amazon Drive
  • Amazon S3 Glacier Storage
  • Backblaze B2 Cloud Storage
  • Google One
  • Dropbox Basic

Here is its cost summarized for 1 year period for 5TB of data.

PRICE  TIME       SERVICE
 $300  1 YEAR(s)  Amazon Drive
 $310  1 YEAR(s)  Google One
 $240  1 YEAR(s)  Amazon S3 Glacier Storage
 $450  1 YEAR(s)  Backblaze B2 Cloud Storage
 $360  1 YEAR(s)  Dropbox Basic

For the Backblaze B2 Cloud Storage I assumed average between upload/download price because upload is two times cheaper then download.

Here is its cost summarized for 5 year period for 5 TB of data.

PRICE  TIME       SERVICE
 $150  5 YEAR(s)  Dell Wyse 3030 LT + 5 TB USB 2.5 Drive
 $230  5 YEAR(s)  Dell Wyse 3030 LT + 5 TB USB 2.5 Drive (assuming drive failed)
$1500  5 YEAR(s)  Amazon Drive
$1550  5 YEAR(s)  Google One
$1200  5 YEAR(s)  Amazon S3 Glacier Storage
$2250  5 YEAR(s)  Backblaze B2 Cloud Storage
$1800  5 YEAR(s)  Dropbox Basic

… but there is also a catch here. Recently I was able to get a lifetime offer for 1 TB of cloud storage. It cost me about $170 for that 1 TB.

This is where it gets interesting – for 5 TB we would have to pay $850 for lifetime cloud storage. Lets calculate where the ‘personal’ NAS is comparable to ‘lifetime’ cloud storage.


PRICE   TIME       SERVICE
 $230   5 YEAR(s)  Dell Wyse 3030 LT + 5 TB USB 2.5 Drive => assuming drive failed 1 time(s)
 $460  10 YEAR(s)  Dell Wyse 3030 LT + 5 TB USB 2.5 Drive => assuming drive failed 2 time(s)
 $690  15 YEAR(s)  Dell Wyse 3030 LT + 5 TB USB 2.5 Drive => assuming drive failed 3 time(s)
 $920  20 YEAR(s)  Dell Wyse 3030 LT + 5 TB USB 2.5 Drive => assuming drive failed 4 time(s)
 $850  UNLIMITED   {5TB unlimited time cloud vendor}

So … it will take you about 20 years of your life (and an assumption that a drive will fail every 5 years with 4 drive fails total) to make it less expensive then the unlimited cloud storage. To be honest – I would get such unlimited cloud storage for most important files and documents for example in 1 TB or less size. Keep an encrypted backup copy the most important files and you are doing better then the classic 3-2-1 backup rule … assuming that you already have one online and one offline backup and also one onsite backup and one offsite backup … and at least two different medium types used πŸ™‚

Drawbacks

WiFi is not supported and network requires restart after boot. Besides these I did not find any other issues.

Connect FreeBSD 13.2 to FreeIPA/IDM

About half a year ago I wrote about how to Connect FreeBSD to FreeIPA/Red Hat Identity Management with available then FreeBSD 13.1-RELEASE version. Time flies and we have newer FreeBSD release around the corner. FreeBSD 13.2 is currently at RC5 level and I believe we should see 13.2-RELEASE official announcement within hours – but even if it would take RC6 and RELEASE being available in weeks later – the instructions will not change for this setup.

This guide will focus only on FreeBSD part of configuring and building packages with needed options to make it connect (and work with) FreeIPA/IDM properly. To have a working FreeIPA/IDM server you need to do instructions from the FreeIPA section of the mentioned above article – up to the FreeBSD Client section. Then – when specified in the article – also the Finish Setup with Web Browser in FreeIPA/IDM Page section needs to be done from the earlier article.

In other words – this article updates the FreeBSD Client section with instructions to use latest upcoming FreeBSD 13.2-RELEASE and newer up-to-date packages versions.

One note about conventions (and colors).

% command                            // command executed on local system
[root@idm ~]# command                // command executed on FreeIPA/IDM server
# diff Makefile.OLD Makefile         // command executed on FreeBSD client system
< krb5>=1.10:security/krb5 \         // parts of configs/commands are colored for better visibility
> krb5-119>=1.10:security/krb5-119 \ // parts of configs/commands are colored for better visibility

FreeBSD Client

We will use these software versions as shown below.

# pkg info | grep -e krb -e sudo -e sssd -e openldap -e samba -e cyrus -e mkhomedir
cyrus-sasl-2.1.28           RFC 2222 SASL (Simple Authentication and Security Layer)
cyrus-sasl-gssapi-2.1.28    SASL GSSAPI authentication plugin
krb5-119-1.19.4             MIT implementation of RFC 4120 network authentication service
openldap26-client-2.6.4     Open source LDAP client implementation
pam_mkhomedir-0.2           Create HOME with a PAM module on demand
samba413-4.13.17_4          Free SMB/CIFS and AD/DC server and client for Unix
sssd-1.16.5_8               System Security Services Daemon
sudo-1.9.13p3               Allow others to run commands as root

This is the main /etc/rc.conf config file.

# cat /etc/rc.conf
  hostname="fbsd132.vercorp.org"
  ifconfig_em0="inet 10.0.0.50/24"
  defaultrouter="10.0.0.1"
  clear_tmp_enable=YES
  syslogd_flags="-ss"
  sshd_enable=YES
  dumpdev=AUTO
  zfs_enable=YES
  ntpd_enable=YES
  sssd_enable="YES"
  rc_info=NO
  rc_startmsgs=NO

FreeBSD Packages

We will fetch up-to-date FreeBSD Ports tree.

# portsnap auto

We will also configure make(1) to store all its compilation results under /usr/ports/obj dir.

# cat << EOF > /etc/make.conf
WRKDIRPREFIX=/usr/ports/obj
EOF

We will switch to latest branch of pkg(8) packages.

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

# grep latest /etc/pkg/FreeBSD.conf
  url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",

We will install packages that are needed for compilation and also essential pam_mkhomedir package.

# pkg install -y \
    autoconf \
    automake \
    bind-tools \
    c-ares \
    cmocka \
    dialog4ports \
    ding-libs \
    docbook-xsl \
    gettext-tools \
    gmake \
    ldb22 \
    libtool \
    libxslt \
    m4 \
    nss \
    pcre \
    pkgconf \
    pam_mkhomedir

Now we will install our ‘core’ packages – and delete them right after – to waste less time on compilation.

# pkg install   -y krb5-119 sudo cyrus-sasl cyrus-sasl-gssapi openldap26-client samba413

# pkg delete -f -y krb5-119 sudo cyrus-sasl cyrus-sasl-gssapi openldap26-client samba413

# pkg install   -y krb5-119

By default the security/krb5-119 package is built without LDAP option. This is what we need for this step. We will later rebuild it with LDAP option.

In case something changed between posting that article and LDAP option being included or not in the security/krb5-119 package – below are instructions to rebuild it without LDAP option.

# cd /usr/ports/security/krb5-119

# make config
[ ] LDAP

# make build deinstall install

Now we need to rebuild security/cyrus-sasl2-gssapi package with GSSAPI_MIT option enabled.

# cd /usr/ports/security/cyrus-sasl2-gssapi

# make config
(x) GSSAPI_MIT

# make build deinstall install

Next rebuild the net/openldap26-client package with GSSAPI option enabled.

# cd /usr/ports/net/openldap26-client

# make config
[x] GSSAPI

# make build deinstall install

Next we are back to security/krb5-119 package and now it needs to be rebuilt with LDAP option.

# cd /usr/ports/security/krb5-119

# make config
[x] LDAP

# make build deinstall install

Now with security/sssd we will need a small patch because without it security/sssd will try to use newer security/krb5-120 package – which does not work with FreeIPA/IDM for now.

# cd /usr/ports/security/sssd

# cp Makefile Makefile.OLD

# sed -i '' 's|krb5>=1.10:security/krb5|krb5-119>=1.10:security/krb5-119|g' Makefile

# diff Makefile.OLD Makefile
32c32
<               krb5>=1.10:security/krb5 \
---
>               krb5-119>=1.10:security/krb5-119 \


Now the rebuild instructions.

# cd /usr/ports/security/sssd

# make config
[x] SMB

# make build deinstall install

Now we need to delete security/sssd and security/sudo packages to rebuild them again … yes its stupid.

# pkg delete -f sudo sssd

We now need to build and install security/sudo without PAM option and with SSSD option and with GSSAPI_MIT option enabled.

# cd /usr/ports/security/sudo

# make config
[ ] PAM
[x] SSSD
--- Kerberos 5 Authentication
(*) GSSAPI_MIT

# make build deinstall install

FreeBSD Setup

We now move to the configuration process as we have our packages installed.

Create needed dirs.

# mkdir -p \
    /usr/local/etc/ipa \
    /var/log/sssd \
    /var/run/sss/private \
    /var/db/sss

Set system hostname.

# grep hostname /etc/rc.conf
  hostname="fbsd132.vercorp.org"

# hostname fbsd132.vercorp.org

# hostname
fbsd132.vercorp.org

# cat << EOF > /etc/hosts
::1             localhost localhost.my.domain
127.0.0.1       localhost localhost.my.domain
10.0.0.50       fbsd132.vercorp.org fbsd132
10.0.0.40       idm.vercorp.org idm
EOF

# cat /etc/hosts
::1             localhost localhost.my.domain
127.0.0.1       localhost localhost.my.domain
10.0.0.50       fbsd132.vercorp.org fbsd132
10.0.0.40       idm.vercorp.org idm

Fetch the FreeIPA/IDM certificate.

# fetch -o /usr/local/etc/ipa/ca.crt http://10.0.0.40/ipa/config/ca.crt
/usr/local/etc/ipa/ca.crt                             1635  B 8227 kBps    00s

FreeIPA/IDM Setup Part

We now need to execute instructions on /IDM to connect FreeBSD to it.

Add A and PTR DNS records for our 10.0.0.50 IP address with fbsd132.vercorp.org hostname.

We also need to generate key for fbsd132.vercorp.org system.

[root@idm ~]# kinit admin
Password for admin@VERCORP.ORG:

[root@idm ~]# ipa dnsrecord-add vercorp.org fbsd132 --a-rec=10.0.0.50 --a-create-reverse
  Record name: fbsd132
  A record: 10.0.0.50

[root@idm ~]# ipa host-add fbsd132.vercorp.org
--------------------------------
Added host "fbsd132.vercorp.org"
--------------------------------
  Host name: fbsd132.vercorp.org
  Principal name: host/fbsd132.vercorp.org@VERCORP.ORG
  Principal alias: host/fbsd132.vercorp.org@VERCORP.ORG
  Password: False
  Keytab: False
  Managed by: fbsd132.vercorp.org

[root@idm ~]# ipa-getkeytab -s idm.vercorp.org \
                            -p host/fbsd132.vercorp.org@VERCORP.ORG \
                            -k /root/fbsd132.vercorp.org.keytab
Keytab successfully retrieved and stored in: /root/fbsd132.vercorp.org.keytab

[root@idm ~]# cp \
                /root/fbsd132.vercorp.org.keytab \
                /usr/share/ipa/html/fbsd132.vercorp.org.keytab

[root@idm ~]# chmod 644 /usr/share/ipa/html/fbsd132.vercorp.org.keytab

Now we will get fbsd132.vercorp.org system key from FreeIPA/IDM server.

# fetch -o /usr/local/etc/ipa/krb5.keytab http://10.0.0.40/ipa/config/fbsd132.vercorp.org.keytab
/usr/local/etc/ipa/krb5.keytab                         176  B  975 kBps    00s

# chmod 600 /usr/local/etc/ipa/krb5.keytab

Now we will move to creating needed config files.

The /usr/local/etc/openldap/ldap.conf file.

# cat << EOF > /usr/local/etc/openldap/ldap.conf
BASE        dc=org,dc=vercorp
URI         ldap://idm.vercorp.org/
#SIZELIMIT  12
#TIMELIMIT  15
#DEREF      never
SASL_MECH   GSSAPI
SASL_REALM  VERCORP.ORG
ssl         start_tls
TLS_CACERT  /usr/local/etc/ipa/ca.crt
EOF

… and /etc/krb5.conf file.

# cat << EOF > /etc/krb5.conf
[libdefaults]
  default_realm = VERCORP.ORG
  default_keytab_name = FILE:/usr/local/etc/ipa/krb5.keytab
  default_tkt_enctypes = aes256-cts des-cbc-crc aes128-cts arcfour-hmac
  default_tgs_enctypes = aes256-cts des-cbc-crc aes128-cts arcfour-hmac
  dns_lookup_realm = false
  dns_lookup_kdc = false
  rdns = false
  ticket_lifetime = 24h
  forwardable = yes

[realms]
  VERCORP.ORG = {
    kdc = idm.vercorp.org:88
    master_kdc = idm.vercorp.org:88
    admin_server = idm.vercorp.org:749
    default_domain = vercorp.org
    pkinit_anchors = FILE:/usr/local/etc/ipa/ca.crt
}

[domain_realm]
  .vercorp.org = VERCORP.ORG
  vercorp.org = VERCORP.ORG

[logging]
  kdc = FILE:/var/log/krb5/krb5kdc.log
  admin_server = FILE:/var/log/krb5/kadmin.log
  kadmin_local = FILE:/var/log/krb5/kadmin_local.log
  default = FILE:/var/log/krb5/krb5lib.log
EOF

… and /usr/local/etc/sssd/sssd.conf file.

# cat << EOF > /usr/local/etc/sssd/sssd.conf

[domain/vercorp.org]
# debug_level = 9
cache_credentials = True
krb5_store_password_if_offline = True
krb5_realm = VERCORP.ORG
ipa_domain = vercorp.org
id_provider = ipa
auth_provider = ipa
access_provider = ipa
ipa_hostname = fbsd132.vercorp.org
chpass_provider = ipa
ipa_server = _srv_, idm.vercorp.org
ldap_tls_cacert = /usr/local/etc/ipa/ca.crt
krb5_keytab = /usr/local/etc/ipa/krb5.keytab

[sssd]
services = nss, pam, ssh, sudo
config_file_version = 2
domains = vercorp.org

[nss]
filter_users = root,toor
homedir_substring = /usr/home/%u

[pam]

[sudo]
# debug_level = 0x3ff0

[ssh]
EOF

# chmod 600 /usr/local/etc/sssd/sssd.conf

FreeBSD have user account under /usr/home to make sure /home also points there.

# ln -s /usr/home /home

Now we need modify several FreeBSD Base System files such as /etc/nsswitch.conf or PAM and SSH configuration.

# cat << EOF > /etc/nsswitch.conf
#
# nsswitch.conf(5) - name service switch configuration file
# $FreeBSD$
#
group: files sss
group_compat: nis
hosts: files dns
# netgroup: compat
networks: files
passwd: files sss
passwd_compat: nis
shells: files
services: compat
services_compat: nis
protocols: files
rpc: files
sudoers: sss files
netgroup: files
EOF

The /etc/pam.d/system file.

# cat << EOF > /etc/pam.d/system
#
# $FreeBSD$
#
# System-wide defaults
#

# auth
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so       no_warn allow_local
auth            sufficient      pam_krb5.so             no_warn try_first_pass
#auth           sufficient      pam_ssh.so              no_warn try_first_pass
auth            sufficient      /usr/local/lib/pam_sss.so       use_first_pass
auth            required        pam_unix.so             no_warn try_first_pass nullok

# account
#account        required        pam_krb5.so
account         required        pam_login_access.so
account         required        pam_unix.so
account         required        /usr/local/lib/pam_sss.so       ignore_unknown_user ignore_authinfo_unavail

# session
#session        optional        pam_ssh.so              want_agent
session         required        pam_lastlog.so          no_fail
session         required        /usr/local/lib/pam_mkhomedir.so mode=0700

# password
#password       sufficient      pam_krb5.so             no_warn try_first_pass
password        sufficient      /usr/local/lib/pam_sss.so       use_authtok
password        required        pam_unix.so             no_warn try_first_pass
EOF

The /etc/pam.d/sshd file.

# cat << EOF > /etc/pam.d/sshd
#
# $FreeBSD$
#
# PAM configuration for the "sshd" service
#

# auth
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so       no_warn allow_local
auth            sufficient      pam_krb5.so             no_warn try_first_pass
#auth           sufficient      pam_ssh.so              no_warn try_first_pass
auth            sufficient      /usr/local/lib/pam_sss.so       use_first_pass
auth            required        pam_unix.so             no_warn try_first_pass

# account
account         required        pam_nologin.so
#account        required        pam_krb5.so
account         required        pam_login_access.so
account         required        pam_unix.so
account         required        /usr/local/lib/pam_sss.so       ignore_unknown_user ignore_authinfo_unavail

# session
#session        optional        pam_ssh.so              want_agent
session         required        pam_permit.so
session         required        /usr/local/lib/pam_mkhomedir.so mode=0700

# password
#password       sufficient      pam_krb5.so             no_warn try_first_pass
password        sufficient      /usr/local/lib/pam_sss.so       use_authtok
password        required        pam_unix.so             no_warn try_first_pass
EOF

The /etc/ssh/ssh_config file.

# cat << EOF >> /etc/ssh/ssh_config
GSSAPIAuthentication yes
EOF

The /etc/ssh/sshd_config file.

# cat << EOF >> /etc/ssh/sshd_config
GSSAPIAuthentication yes
UsePAM yes
EOF

Automatic startup of sssd(8) daemon (not to confuse with sshd(8)) needs to be also configured.

# service sssd enable
# service sssd start

Now … go to the original Connect FreeBSD to FreeIPA/Red Hat Identity Management article and ‘do’ the Finish Setup with Web Browser in FreeIPA/IDM Page section instructions – all the way up to the FreeBSD FreeIPA Login Test section.

FreeBSD FreeIPA Login Test

Now we can try to login to our FreeBSD client … but first several other things.

If you just created your ‘regular’ FreeIPA/IDM user – you need to set a permanent password for it. Its not possible by first logging to the FreeBSD system. You will get following error on the FreeBSD client.

# grep sshd /var/log/messages
(...)
Mar 24 20:51:46 fbsd132 [sssd[krb5_child[779]]][779]: Password has expired
(...)

You need to change this password by logging into the FreeIPA/IDM Linux system. Here is how.

% ssh 10.0.0.40 -l vermaden
(vermaden@10.0.0.40) Password:
(vermaden@10.0.0.40) Password expired. Change your password now.
Current Password:
(vermaden@10.0.0.40) New password:
(vermaden@10.0.0.40) Retype new password:
Could not chdir to home directory /home/vermaden: No such file or directory
[vermaden@idm /]$ exit

Another thing – make sure that time is synchronized between the client and FreeIPA/IDM systems – you will get following error on the FreeBSD client if they are not in sync.

# grep sssd /var/log/messages
(...)
Mar 24 20:51:46 fbsd132 [sssd[krb5_child[779]]][779]: Clock skew too great
(...)

… or …

PAM: User account has expired for vermaden from 10.0.0.3

Here is fast way to sync their times against pool.ntp.org host.

Feel free to setup some permanent time sync solution on both of them. You can also enable NTP server on FreeIPA/IDM during its configuration and sync all FreeIPA/IDM clients against it.

# ntpdate pool.ntp.org

# date
Wed Mar 29 10:34:14 CEST 2023

[root@idm ~]# chronyd -q 'server pool.ntp.org iburst' || chronyc -a 'burst 4/4'

[root@idm ~]# date
Wed Mar 29 10:34:14 CEST 2023

Now we can finally login to our FreeBSD client.

% ssh 10.0.0.50 -l vermaden
(vermaden@10.0.0.50) Password:

vermaden@fbsd132:~ $ uname -prism
FreeBSD 13.2-RC3 amd64 amd64 GENERIC

vermaden@fbsd132:~ $ grep $( whoami ) /etc/passwd

vermaden@fbsd132:~ $ id
uid=1408200003(vermaden) gid=1408200000(admins) groups=1408200000(admins)


Done. Seems to work properly.

Latest Samba 4.16

You can also use latest Samba 4.16 version instead of the 4.13 default one.

The needed changes are below – to be executed before package building.

# cat << EOF >> /etc/make.conf
# net/samba416
DEFAULT_VERSIONS+=samba=4.16
EOF

Rebuilding process for net/samba416 package.

# cd /usr/ports/net/samba416

# make config
(*) GSSAPI_MIT

# make build deinstall install

Feel free to share your thoughts on this in the comments section.

EOF

FreeBSD Home Audio Studio

Another guest post by @NeoMoevius from Twitter.

Same as earlier with the Native Urban Terror on FreeBSD article.

This time it will be about setting up Home Audio Studio on a FreeBSD 13.1 system.

w701-ardour

The idea is to use software like:

  • Jackaudio/jack
  • Qtractoraudio/qtractor
  • Ardouraudio/ardour
  • MuSE Sequenceraudio/muse-sequencer

The first step is to setup Jack on FreeBSD – make sure to setup the realtime mode – this is very important.

Add mac_priority to /etc/rc.conf file and load the mac_priority kernel module.

# echo 'kld_list="${kld_list} mac_priority"' >> /etc/rc.conf

# kldload mac_priority

Then add yourself to realtime group.

# pw groupmod realtime -m yourself

# grep realtime /etc/group         
realtime:*:47:yourself

You will need to install audio/jack package.

% pkg which -o $( which jackd )
/usr/local/bin/jackd was installed by package audio/jack

The /etc/rc.conf part to run Jack is below.

# grep jack /etc/rc.conf
  jackd_enable="YES"
  jackd_user="username"
  jackd_rtprio="YES"
  jackd_args="-r -d oss -r44100 -p1024 -n2 -w16 -i4 -o8 -C /dev/dsp0 -P /dev/dsp0"

The Qtractor will also require audio/alsa-seq-server to work. The good part is that it (the audio/alsa-seq-server package) comes with rc(8) script to start it so you may enable it with service(8) or sysrc(8) commands.

% /usr/local/etc/rc.d/alsa_seq_server rcvar
# alsa_seq_server
#
alsa_seq_server_enable="NO"
#   (default: "")

# service alsa_seq_server enable
alsa_seq_server enabled in /etc/rc.conf

# sysrc alsa_seq_server_enable=YES
alsa_seq_server_enable: YES -> YES

Now all of the above DAW software (or other music programs) should be working properly.

EOF

Print on FreeBSD

Nothing compares more to the sense of power UNIX sysadmin experiences when being able to print from a command line on its UNIX system :p

I kinda omitted this topic (printing) for quite a lot of time – when I was using FreeBSD in the corporate environment I still printed from Windows VM on a network printers. Then they forced me to use Windows anyway. At home my wife always had a printer configured (as she uses it more) and the other printer also had USB port – so you could just copy the PDF or JPG file to a USB pendrive – attach it the printer and hit print button for the selected files. No configuration needed.

I was also disappointed when I tried several years ago to configure USB printer on FreeBSD … and failed.

Recently I though that its about fucking time to dig into that topic and have at least one working printer on FreeBSD.

cups
This guide will focus on using two printers with CUPS on FreeBSD:

  • HP Color LaserJet 200 M251nw Printer (attached over TCP/IP network)
  • Samsung Black/White ML-1915 Printer (local USB attached)

There will be two different prompt types used for the commands:

  • starting with % for commands that can be executed as regular user or root
  • starting with # for commands that must be executed as root user

The Table of Contents for this article is shown below.

  • CUPS Packages and Service Configuration
  • Network Printer – HP M251nw
  • Try to Print Some Document
  • USB Printer – Samsung ML-1915
  • Choose Default Printer
  • CUPS Printers Config
  • Command Line Printing
  • Last Chance Fancy Pants
  • Summary

CUPS Packages and Service Configuration

There are only three pkg(8) packages needed for my printers – these are:

# pkg install cups cups-filters splix

We will also need to add some lines to the /etc/devfs.rules file.

These lines are important for printing with CUPS:

add path 'lpt*'      mode 0660 group cups
add path 'ulpt*'     mode 0660 group cups
add path 'unlpt*'    mode 0660 group cups

The rest of the config is just the rest of my desktop config and can be omitted for printing.

The entire /etc/devfs.rules file looks as follows.

% cat /etc/devfs.rules
[desktop=10]
add path 'lpt*'      mode 0660 group cups
add path 'ulpt*'     mode 0660 group cups
add path 'unlpt*'    mode 0660 group cups
add path 'acd*'      mode 0660 group operator
add path 'cd*'       mode 0660 group operator
add path 'da*'       mode 0660 group operator
add path 'pass*'     mode 0660 group operator
add path 'xpt*'      mode 0660 group operator
add path 'fd*'       mode 0660 group operator
add path 'md*'       mode 0660 group operator
add path 'uscanner*' mode 0660 group operator
add path 'ugen*'     mode 0660 group operator
add path 'usb/*'     mode 0660 group operator
add path 'video*'    mode 0660 group operator
add path 'cuse*'     mode 0660 group operator

We will also need to add devfs_system_ruleset=desktop to the /etc/rc.conf file.

% grep desktop /etc/rc.conf
  devfs_system_ruleset=desktop

Now we need to restart the devfs daemon to read new config.

# service devfs restart

We can also make sure that devfs(8) know our ruleset config.

# devfs rule -s 10 show | column -t
100   path  acd*       group  operator  mode  660
200   path  cd*        group  operator  mode  660
300   path  da*        group  operator  mode  660
400   path  pass*      group  operator  mode  660
500   path  xpt*       group  operator  mode  660
600   path  fd*        group  operator  mode  660
700   path  md*        group  operator  mode  660
800   path  uscanner*  group  operator  mode  660
900   path  lpt*       group  cups      mode  660
1000  path  ulpt*      group  cups      mode  660
1100  path  unlpt*     group  cups      mode  660
1200  path  ugen*      group  operator  mode  660
1300  path  usb/*      group  operator  mode  660
1400  path  video*     group  operator  mode  660
1500  path  cuse*      group  operator  mode  660

The column(1) is not needed here – I used it only to format the output.

What amaze me to this day that column(1) command is still not available on such enterprise (and overpriced also) IBM AIX system πŸ™‚

Here are the contents of fresh CUPS installation at /usr/local/etc/cups dir.

# tree -F --dirsfirst /usr/local/etc/cups
/usr/local/etc/cups
β”œβ”€β”€ ppd/
β”œβ”€β”€ ssl/
β”œβ”€β”€ cups-files.conf
β”œβ”€β”€ cups-files.conf.sample
β”œβ”€β”€ cupsd.conf
β”œβ”€β”€ cupsd.conf.sample
β”œβ”€β”€ snmp.conf
└── snmp.conf.sample

3 directories, 6 files

You will need to add cupsd_enable=YES to the /etc/rc.conf file.

% grep cups /etc/rc.conf
  cupsd_enable=YES

Make sure that cupsd service is started and running.

# service cupsd start
Starting cupsd.

# service cupsd status
cupsd is running as pid 44515.

# sockstat -l4 | grep -e ADDRESS -e 631
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
root     cupsd      44515 6  tcp4   127.0.0.1:631         *:*

Just in case – here are the groups in which my vermaden user is:

% id | tr ',' '\n'
uid=1000(vermaden) gid=1000(vermaden) groups=1000(vermaden)
0(wheel)
5(operator)
44(video)
69(network)
145(webcamd)
920(vboxusers)

It was not needed to add my vermaden user to the cups group to print – but feel free to also test that if you face any problems.

Network Printer – HP M251nw

First I will go with the TCP/IP attached network printer – HP M251nw.

printer-HP-M251nw
Before doing any steps or configuration on FreeBSD part we first need to connect that printer to the TCP/IP network. As the HP M251nw printer has WiFi – I decided to connect it to my wireless WiFi router instead of using RJ45 cable. I will not document that part as HP already provides decent guide on how to achieve that – https://youtu.be/jLDzQBAtKyQ – on YouTube service.

In my case I used the 10.0.0.9 IP address and I configured my WiFi router to always attach that MAC address to that IP address.

printer-HP-M251nw-www

Next step is to open http://localhost:631/ page in your browser. You will see default CUPS web interface.

cups-page-01

Hit the Administration tab on the top. Then click the Add Printer button in the middle of the page – you will be asked for username and password – use your username and your password here.

cups-page-03-admin-01-ADD-PRINTER

The HP M251nw network attached browser has already been detected by CUPS. Select it and click Continue button.

cups-page-03-admin-03-ADD-PRINTER

CUPS will suggest some long names and description as showed below.

cups-page-03-admin-04-ADD-PRINTER

… but we will use simpler and shorter name instead.

cups-page-03-admin-05-ADD-PRINTER

Next we need to choose which driver to use.

We will not find a HP M251nw driver on the CUPS list but there are two drivers that will work here:

  • HP LaserJet Series PCL 6 CUPS (en)
  • HP Color LaserJet Series PCL 6 CUPS (en)

As HP M251nw is color printer we will choose HP Color LaserJet Series PCL 6 CUPS here.

cups-page-03-admin-06-ADD-PRINTER-driver

After a moment we will see a message that HP M251nw printer has been successfully added to CUPS.

cups-page-03-admin-07-ADD-PRINTER

You can notice that new PPD file appeared at CUPS dir named exactly like the printer name.

% ls -l /usr/local/etc/cups/ppd
total 9K
-rw-r----- 1 root cups 9721 2023-02-06 11:24 HP-M251nw.ppd
-rw-r----- 1 root cups 9736 2023-02-06 11:23 HP-M251nw.ppd.O

This is how our HP M251nw printer status page looks like.

cups-page-03-admin-08-ADD-PRINTER

We should now setup the default printing options. From the Administration drop down menu select Set Default Options option. The only things I selected/set that are different from the CUPS defaults are A4 paper size and 1200 DPI resolution.

cups-page-03-admin-09-ADD-PRINTER-prefs

Try to Print Some Document

I will now use Atril PDF viewer to test how the printing on the HP M251nw works – I used a small one page PDF file with one of my old guides – the ZFS Madness one from 2014. From the File menu select Print… option – or just hit [CTRL]+[P] shortcut.

PDF-print-01

Then select HP-M251nw printer from the list and hit the Print button below.

PDF-print-02

After some noises and time (not much later) the printer dropped a printed page. Seems to work properly.

real-printed-page

Looks good.

Lets now add USB printer.

USB Printer – Samsung ML-1915

To get needed PPD driver for the Samsung ML-1915 printer we installed the print/splix package.

printer-SAMSUNG-ML-1915

Here is the exact driver we will use.

% pkg info -l splix | grep 1915
        /usr/local/share/cups/model/samsung/ml1915.ppd

Before attaching the Samsung ML-1915 printer to your computer you may check what devices devd(8) will create.

First power on the Samsung ML-1915 printer.

Then attach the USB cable from the printer to your FreeBSD box (assuming that printer has AC power and is powered on).

You should see something similar from devd(8) daemon.

# nc -U /var/run/devd.pipe
!system=DEVFS subsystem=CDEV type=CREATE cdev=usb/0.3.0
!system=DEVFS subsystem=CDEV type=CREATE cdev=ugen0.3
!system=DEVFS subsystem=CDEV type=CREATE cdev=usb/0.3.2
!system=DEVFS subsystem=CDEV type=CREATE cdev=usb/0.3.3
!system=USB subsystem=DEVICE type=ATTACH ugen=ugen0.3 cdev=ugen0.3 vendor=0x04e8 product=0x3297 devclass=0x00 devsubclass=0x00 sernum="Z2L9BACSC00641K." release=0x0100 mode=host port=2 parent=ugen0.2
!system=USB subsystem=INTERFACE type=ATTACH ugen=ugen0.3 cdev=ugen0.3 vendor=0x04e8 product=0x3297 devclass=0x00 devsubclass=0x00 sernum="Z2L9BACSC00641K." release=0x0100 mode=host interface=0 endpoints=2 intclass=0x07 intsubclass=0x01 intprotocol=0x02
!system=DEVFS subsystem=CDEV type=CREATE cdev=ulpt0
!system=DEVFS subsystem=CDEV type=CREATE cdev=unlpt0
+ulpt0 at bus=0 hubaddr=2 port=2 devaddr=3 interface=0 ugen=ugen0.3 vendor=0x04e8 product=0x3297 devclass=0x00 devsubclass=0x00 devproto=0x00 sernum="Z2L9BACSC00641K." release=0x0100 mode=host intclass=0x07 intsubclass=0x01 intprotocol=0x02 on uhub4

These are the created devices.

% ls -ltra /dev | tail -3
lrw-rw----  1 root     operator      9 2023-02-06 11:38 ugen0.3 -> usb/0.3.0
crw-rw----  1 root     cups     2, 113 2023-02-06 11:38 ulpt0
crw-rw----  1 root     cups     2, 114 2023-02-06 11:38 unlpt0

They are created with proper cups group.

Now we will go to the CUPS web page at http://localhost:631/ again to add the Samsung ML-1915 printer.

Go again to the Administration tab and click Add Printer button.

cups-page-03-admin-01-ADD-PRINTER

The Samsung ML-1915 should be already detected as local printer as shown below.

cups-samsung-01-ADD-PRINTER

Select it and hit Continue button.

As earlier we will use shorter more reasonable name.

cups-samsung-03-ADD-PRINTER

We will then select Samsung ML-1915, 2.0.0 (en, en) driver for this printer.

cups-samsung-04-ADD-PRINTER

… and Samsung ML-1915 black/white printer has been added.

cups-samsung-06-ADD-PRINTER

Same as earlier the PPD file is copied to the /usr/local/etc/cups/ppd CUPS dir.

% ls -l /usr/local/etc/cups/ppd
total 14K
-rw-r----- 1 root cups  9721 2023-02-06 11:24 HP-M251nw.ppd
-rw-r----- 1 root cups  9736 2023-02-06 11:23 HP-M251nw.ppd.O
-rw-r----- 1 root cups 12391 2023-02-06 11:58 Samsung-ML-1915.ppd

You now have two printers configured in CUPS.

cups-samsung-07-ADD-PRINTER

Choose Default Printer

I will now choose the HP M251nw printer as the default for two reasons. First – its always available as its attached over WiFi. Second – its more powerful and provides color at the same time.

To do that I went to the Printers and clicked the HP M251nw printer.

cups-samsung-08-ADD-PRINTER

Next from the Administration drop down menu I have chosen Set As Server Default option.

cups-samsung-09-ADD-PRINTER

From now on – if not explicitly specified – all the print jobs will land on the HP M251nw printer.

cups-samsung-10-ADD-PRINTER

CUPS Printers Config

After our actions CUPS stored two printers configuration in its /usr/local/etc/cups/printers.conf config file.

# cat /usr/local/etc/cups/printers.conf
# Printer configuration file for CUPS v2.4.2
# Written by cupsd
# DO NOT EDIT THIS FILE WHEN CUPSD IS RUNNING
NextPrinterId 3
<DefaultPrinter HP-M251nw>
PrinterId 1
UUID urn:uuid:b760d323-5f46-36cd-4ca0-d9015c9fb7ca
Info 
Location 
MakeModel HP Color LaserJet Series PCL 6 CUPS
DeviceURI socket://10.0.0.9
State Idle
StateTime 1675683146
ConfigTime 1675679066
Type 8400972
Accepting Yes
Shared No
JobSheets none none
QuotaPeriod 0
PageLimit 0
KLimit 0
OpPolicy default
ErrorPolicy stop-printer
Attribute marker-colors \#000000,#00FFFF,#FF00FF,#FFFF00
Attribute marker-levels 99,98,98,99
Attribute marker-names Black Cartridge HP CF210X,Cyan Cartridge HP CF211A,Magenta Cartridge HP CF213A,Yellow Cartridge HP CF212A
Attribute marker-types toner,toner,toner,toner
Attribute marker-change-time 1675683146
</DefaultPrinter>
<Printer Samsung-ML-1915>
PrinterId 2
UUID urn:uuid:4434851b-5516-3b73-702a-286dabf630b0
Info 
Location 
MakeModel Samsung ML-1915, 2.0.0
DeviceURI usb://Samsung/ML-191x%20252x%20Series?serial=Z2L9BACSC00641K.
State Idle
StateTime 1675681099
ConfigTime 1675681099
Type 12372
Accepting Yes
Shared No
JobSheets none none
QuotaPeriod 0
PageLimit 0
KLimit 0
OpPolicy default
ErrorPolicy stop-printer
</Printer>

Command Line Printing

Besides being able to print from graphical applications that support CUPS we can also print directly from the command line if needed.

Use lpstat(1) command to see all available printers – including the default one.

% lpstat -p -d
printer HP-M251nw is idle.  enabled since Mon Feb  6 12:02:39 2023
printer Samsung-ML-1915 is idle.  enabled since Mon Feb  6 11:58:19 2023
system default destination: HP-M251nw

You can check more information about the default printer with lpoptions(1) command.

% lpoptions -l
PageSize/Media Size: Letter Legal Executive Tabloid A3 *A4 A5 B5 EnvISOB5 Env10 EnvC5 EnvDL EnvMonarch
InputSlot/Media Source: *Default Auto MultiPurpose Upper Lower LargeCapacity Manual Envelope
ColorModel/Output Mode: *RGB Gray
Resolution/Output Resolution: 150dpi 300dpi 600dpi *1200dpi
Duplex/Double-Sided Printing: *None DuplexNoTumble DuplexTumble
OptionDuplex/Duplexer: True *False

… or even more details and information when executed without arguments.

I have used tr(1) tool to make the output more readable as by default all this information is separated only by spaces.

% lpoptions | tr ' ' '\n'
copies=1
device-uri=socket://10.0.0.9
finishings=3
job-cancel-after=10800
job-hold-until=no-hold
job-priority=50
job-sheets=none,none
marker-change-time=1675681359
marker-colors=#000000,#00FFFF,#FF00FF,#FFFF00
marker-levels=99,98,98,99
marker-names='Black\
Cartridge\
HP\
CF210X,Cyan\
Cartridge\
HP\
CF211A,Magenta\
Cartridge\
HP\
CF213A,Yellow\
Cartridge\
HP\
CF212A'
marker-types=toner,toner,toner,toner
number-up=1
print-color-mode=color
printer-commands=AutoConfigure,Clean,PrintSelfTestPage
printer-info
printer-is-accepting-jobs=true
printer-is-shared=false
printer-is-temporary=false
printer-location
printer-make-and-model='HP
Color
LaserJet
Series
PCL
6
CUPS'
printer-state=3
printer-state-change-time=1675681359
printer-state-reasons=none
printer-type=10629196
printer-uri-supported=ipp://localhost/printers/HP-M251nw

We will now print the same PDF document using command line with lp(1) command.

% lp ZFS-Madness-2014.pdf
request id is HP-M251nw-02 (1 file(s))

Believe me or not – that PDF document got printed exactly the same as when invoked from Atril PDF browser.

Last Chance Fancy Pants

There is of course a chance that your printer will not be detected – or it will not print – or the driver will not attach to it properly … life happens.

What then? Fuck it. There is even more fun way to print … even without any drivers or configuration … directly with nc(1) command πŸ™‚

First lets check of your printer listens on 9100 port – this is called HP JetDirect.

% grep 9100 /etc/services
jetdirect       9100/tcp   #HP JetDirect card
pdl-datastream  9100/tcp   #Printer PDL Data Stream
pdl-datastream  9100/udp   #Printer PDL Data Stream

% nmap -A 10.0.0.9
Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-06 23:41 CET
Nmap scan report for 10.0.0.9
Host is up (0.0072s latency).
Not shown: 988 closed tcp ports (conn-refused)
PORT     STATE SERVICE        VERSION
21/tcp   open  ftp            oftpd
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_.
|_ftp-bounce: bounce working!
| ftp-syst:
|_  SYST: .
23/tcp   open  telnet         HP LaserJet printer telnetd (busy)
80/tcp   open  soap           gSOAP 2.7
| http-server-header:
|   Virata-EmWeb/R6_2_1
|_  gSOAP/2.7
81/tcp   open  tcpwrapped
82/tcp   open  tcpwrapped
83/tcp   open  tcpwrapped
443/tcp  open  ssl/tcpwrapped
| ssl-cert: Subject: commonName=NPI04344D/organizationName=Hewlett-Packard Co.
| Not valid before: 2012-09-01T00:00:00
|_Not valid after:  2022-09-01T00:00:00
|_http-server-header: gSOAP/2.7
|_ssl-date: TLS randomness does not represent time
515/tcp  open  printer
631/tcp  open  soap           gSOAP 2.7
| http-server-header:
|   Virata-EmWeb/R6_2_1
|_  gSOAP/2.7
5222/tcp open  tcpwrapped
| xmpp-info:
|   STARTTLS Failed
|   info:
|     features:
|     auth_mechanisms:
|     xmpp:
|     unknown:
|     compression_methods:
|     errors:
|       (timeout)
|_    capabilities:
8080/tcp open  soap           gSOAP 2.7
| http-server-header:
|   Virata-EmWeb/R6_2_1
|_  gSOAP/2.7
9100/tcp open  jetdirect?
Service Info: OS: Unix; Device: printer

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 20.37 seconds

Lets try to connect to it with nc(1) tool.

% nc -v 10.9 9100
Connection to 10.9 9100 port [tcp/jetdirect] succeeded!

… and yes you do not have to always type that whole 10.0.0.9 address as the middle zeroes can be omitted and 10.9 will be interpretted as 10.0.0.9 address.

Something basic for a start – a plain text print.

% lsblk | nc 10.9 9100

In a moment you should have the output of lsblk(8) command printed on a page.

Lets try something more fancy like a PDF file then.

% nc 10.9 9100 < ZFS-Madness-2014.pdf

Yep. Printed. No CUPS configuration needed here.

Maybe I should start the article with that instead πŸ™‚

Summary

Not sure what I can add here as I am definitely not printing expert.

Hope these instructions will help you to setup your printer on FreeBSD (or any other CUPS supported) system.

EOF

Keep FreeBSD Desktop Updated

While its relatively easy (or brain dead easy with GhostBSD or NomadBSD distributions) to install and configure a FreeBSD Desktop – one have to keep in mind that its also important to keep that system updated and secure.

There are many aspects about FreeBSD to keep it updates and secured.

The Table of Contents for this article is shown below:

  • FreeBSD Base System
  • Packages
  • FreeBSD Linux Browser Installer
  • WINE
  • Cargo Packages
  • FreeBSD Ports Tree
  • Summary

Lets now discuss each section one by one.

FreeBSD Base System

First is the FreeBSD Base System which is updated by the frebsd-update(8) utility. It is not often you need to do this – from my experience its once a month need usually.

The list of needed commands are shown below.

# freebsd-version
# frebsd-update fetch
# frebsd-update install

While the freebsd-version(1) will tell you what version you are currently running the freebsd-update(8) will help you to update your FreeBSD system to have latest patches installed.

… but when to update the FreeBSD Base System anyway? Well – its quite simple – check the FreeBSD Security Advisories page – and if something posted there affects you – then you should move your ass and update it πŸ™‚

Packages

After you have taken care of the FreeBSD Base System the next one to make sure you are not too much far behind are the FreeBSD packages.

You can of course check if any of your installed packages have any reported security holes as shown below.

# pkg audit -F
vulnxml file up-to-date
0 problem(s) in 0 installed package(s) found.

The above message shows that your installed packages are safe – but its not the message you see the most of the time πŸ™‚

Below are the commands that you would use to update your FreeBSD desktop system.

# pkg upgrade
# pkg autoremove
# pkg clean -y --all

… and yes it does include some extra steps to remove cached packages – and probably now not needed as the are already installed anyway.

I do not think that anything more should be added here – maybe a short mention about the packages branch you are using. The default one is the quarterly branch that has packages build every quarter.

Maybe its sometimes reasonable for the server like environments – but I prefer to have the latest versions of what FreeBSD maintainers do offer in their hard and often underestimated work.

This is why I always use – both on desktop and servers – the latest packages branch.

This means that packages are (re)built once a week or faster and you get what is latest and fresh.

I will not convince you what is better – you will have to decide for yourself.

FreeBSD Linux Browser Installer

The Linux Browser Installer helps a lot on FreeBSD systems. It provides browsers (via the Linux Compatibility Layer) that are not natively available on FreeBSD – but with DRM sh!t needed to access for example Netflix content.

The Linux Browser Installer is easy to install – but its also easy to update.

Below you will find commands that will keep your Linux Browser Installer updated and secure.

# git clone https://github.com/mrclksr/linux-browser-installer.git
# cd linux-browser-installer
# ./linux-browser-installer chroot upgrade

WINE

One may think that WINE is just another package and that it was already updated during the # pkg upgrade cycle – it depends – the default WINE package is for 64bit excusables … but its also possible to run (and often needed) the older 32bit executables.

The problem is that the 32bit environment has its own separate root with its own packages set.

To be honest its not a big deal – you just need to remember to update it along with other things you update periodically πŸ™‚

Below is the command that updates the 32bit WINE binaries/packages.

% /usr/local/share/wine/pkg32.sh upgrade

One of the things you need to keep in mind that it is done by you (user) and not the root user of the machine.

Cargo Packages

While 95% of this topic is covered above – no one prevents you from using the additional Cargo packages – and I do it myself also.

Its just that some software is not yet available by the official FreeBSD packages – but its already official by using the Cargo packages.

I personally use about 10 different Cargo packages that are still not available on the FreeBSD packages.

update

Here are the instructions to keep these Cargo packages updated.

First and most important – you need to install the cargo-update package to be able to update installed Cargo packages.

Then you may just use the other command to have Cargo packages updated.

# cargo install cargo-update
# cargo install-update -a

FreeBSD Ports Tree

Last but not least – the FreeBSD Ports Tree – which even if you only use binary packages – can often come handy in some exceptions.

We all know the ‘default’ rule that mixing Packages and Ports is a bad idea in the FreeBSD world – and I generally agree – its a bad idea if you do not know what you are doing.

If you do know what you are doing – you may mix anything with everything – just do not spam the FreeBSD Forums for help later πŸ™‚

The tool to update the local FreeBSD Ports Tree on your machine is still portsnap(8) and the auto argument is usually more then enough.

# portsnap auto

From the other things – you may want to setup the WRKDIRPREFIX variable to have everything built in the /usr/ports/obj directory – to have everything in one place.

# grep WRKDIRPREFIX /etc/make.conf
WRKDIRPREFIX=${PORTSDIR}/obj
# rm -rf \
    /usr/ports/obj \
    /usr/ports/distfiles

I often also clean the /usr/ports/obj and /usr/ports/distfiles directories.

Summary

Besides the things that I have wrote above I also sometimes save some binaries to the ~/scripts/bin path. There is not upgrade path for them besides manually checking the provider page.

Some examples of such software on my system are doso or cpuc ones.

As I do not have anything more to add here – please feel free to comment what is missing in keeping your workstation updated and secure.

EOF

Native Urban Terror on FreeBSD

Welcome to 2023 and let me start a first article of this new year with a … guest post by @NeoMoevius from Twitter. That is right. I did not invented it. I did not created it. I only partially wrote it – treat me as a ghost writer here. ll the thanks and welcomes goes directly to @NeoMoevius – I am just a messenger here πŸ™‚

This post will be about playing (and first building – of course) the Urban Terror game on FreeBSD system. It is about how to build and install Urban Terror 4.3 on FreeBSD without Linux emulation or using WINE. Natively. This will be on the latest and supported FreeBSD 13.1-RELEASE system.

There are not many steps to make it happen. First – just download the official Urban Terror ZIP file.

% mkdir _UT
% cd _UT
% fetch http://cdn.urbanterror.info/urt/43/releases/zips/UrbanTerror434_full.zip
UrbanTerror434_full.zip                         3% of 1403 MB 1836 kBps 11m38s
% unzip UrbanTerror434_full.zip
% cd UrbanTerror43
% pwd
/home/vermaden/_UT/UrbanTerror43

Lets leave that alone for now πŸ™‚

We will also need to install some dependencies.

# pkg install -y \
    devel/sdl20 \
    devel/pkgconf \
    devel/gmake \
    ftp/curl \
    graphics/sdl2_image \
    graphics/sdl2_ttf \
    audio/sdl2_mixer \
    audio/openal-soft

We will now need to download and compile source code of ioquake 3 for Urban Terror.

% mkdir _IOQ3
% cd _IOQ3
% git clone https://github.com/mickael9/ioq3.git
Cloning into 'ioq3'...
remote: Enumerating objects: 28169, done.
Receiving objects:  19% (5353/28169), 6.77 MiB | 2.24 MiB/s
% cd ioq3
% gmake
% echo ${?}
0
% cd build/release-freebsd-x86_64
% ls -l
total 2773K
drwxr-xr-x 2 vermaden vermaden       2 2023-01-20 20:11 autoupdater/
drwxr-xr-x 4 vermaden vermaden     228 2023-01-20 20:12 client/
drwxr-xr-x 2 vermaden vermaden     154 2023-01-20 20:11 ded/
drwxr-xr-x 2 vermaden vermaden     166 2023-01-20 20:12 renderergl1/
drwxr-xr-x 3 vermaden vermaden      77 2023-01-20 20:12 renderergl2/
-rwxr-xr-x 1 vermaden vermaden  862712 2023-01-20 20:12 renderer_opengl1_x86_64.so
-rwxr-xr-x 1 vermaden vermaden 1143552 2023-01-20 20:12 renderer_opengl2_x86_64.so
-rwxr-xr-x 1 vermaden vermaden 2133400 2023-01-20 20:12 urbanterror-m9.x86_64
-rwxr-xr-x 1 vermaden vermaden  970368 2023-01-20 20:11 urbanterror-server-m9.x86_64

The files that are interesting for us are listed below:

  • renderer_opengl1_x86_64.so
  • renderer_opengl2_x86_64.so
  • urbanterror-m9.x86_64
  • urbanterror-server-m9.x86_64

… and now you will need to copy these four files into the Urban Terror folder when you have uncompressed the game.

% cp \
    renderer_opengl1_x86_64.so   \
    renderer_opengl2_x86_64.so   \
    urbanterror-m9.x86_64        \
    urbanterror-server-m9.x86_64 \
    /home/vermaden/_UT/UrbanTerror43

% cd /home/vermaden/_UT/UrbanTerror43

% pwd
/home/vermaden/_UT/UrbanTerror43

% ls -l
total 8495K
drwxr-xr-x 2 vermaden vermaden      30 2023-01-20 20:19 q3ut4/
drwxr-xr-x 3 vermaden vermaden       3 2023-01-20 20:19 Quake3-UrT.app/
-rw-r--r-- 1 vermaden vermaden 1082800 2018-06-21 22:08 Quake3-UrT-Ded.exe
-rwxr-xr-x 1 vermaden vermaden  816002 2018-06-21 22:08 Quake3-UrT-Ded.i386
-rwxr-xr-x 1 vermaden vermaden  961958 2018-06-21 22:08 Quake3-UrT-Ded.x86_64
-rw-r--r-- 1 vermaden vermaden 2634689 2018-06-21 22:08 Quake3-UrT.exe
-rwxr-xr-x 1 vermaden vermaden 1702624 2018-06-21 22:08 Quake3-UrT.i386
-rwxr-xr-x 1 vermaden vermaden 1940280 2018-06-21 22:08 Quake3-UrT.x86_64
-rwxr-xr-x 1 vermaden vermaden  862712 2023-01-20 20:20 renderer_opengl1_x86_64.so
-rwxr-xr-x 1 vermaden vermaden 1143552 2023-01-20 20:20 renderer_opengl2_x86_64.so
-rwxr-xr-x 1 vermaden vermaden 2133400 2023-01-20 20:20 urbanterror-m9.x86_64
-rwxr-xr-x 1 vermaden vermaden  970368 2023-01-20 20:20 urbanterror-server-m9.x86_64

We will now try to start that Urban Terror game.

% pwd
/home/vermaden/_UT/UrbanTerror43

% ./urbanterror-m9.x86_64
ioq3-UrT m9-builds/31 freebsd-x86_64 Jan 20 2023
SSE instruction set enabled
----- FS_Startup -----
We are looking in the current search path:
/home/vermaden/.q3a/q3ut4
./q3ut4
./q3ut4/zUrT43_qvm.pk3 (4 files)
./q3ut4/zUrT43_021.pk3 (85 files)
./q3ut4/zUrT43_020.pk3 (295 files)
./q3ut4/zUrT43_019.pk3 (342 files)
./q3ut4/zUrT43_018.pk3 (801 files)
(...)

Seems to start and work properly.

Here are several shots of what I tried to play it for some single online event.

urban-terror-01

urban-terror-02

urban-terror-03

urban-terror-04

All the screens above are in the windowed more but you can switch between window and full screen with [ALT]+[ENTER] shortcut at anytime. It was just easier for me to catch several shots for this article πŸ™‚

Seems I am definitely not the best at this game :p

urban-terror-05

The Urban Terror game run smooth on my Intel HD Graphics 3000 card.

Fortunately I did not need to switch BIOS settings to start my decade old Nvidia Quadro 2000M monster :p

Not sure what I can add here – definitely a kind thank You for @NeoMoevius for his offer of making this content available for You πŸ™‚

Regards.

Connect FreeBSD to FreeIPA/Red Hat Identity Management

Corporate needs are simple – one ring to rule them all place to get users from. On the open source path there are several ways to achieve that. Alongside ‘plain’ OpenLDAP there is also FreeIPA – which is open source and free version of the Red Hat Identity Management (IDM).

FreeIPA-logo

This guide will show you how to make basic FreeIPA install and connect a FreeBSD 13.1-RELEASE system to it.

logo-freebsd

The Table of Contents for this article looks as follows.

  • Connect FreeBSD to FreeIPA/Red Hat Identity Management
  • FreeIPA
    • FreeIPA Requirements
    • FreeIPA Setup
  • FreeBSD Client
    • FreeBSD Packages
    • FreeBSD Setup
    • FreeIPA/IDM Setup Part
    • Finish Setup with Web Browser in FreeIPA/IDM Page
    • FreeBSD FreeIPA Login Test
  • FreeBSD Jail as FreeIPA/IDM Client
    • Basic FreeBSD Jail Preparations
    • Configure FreeBSD Jail to Connect to FreeIPA/IDM Server
  • Linux FreeIPA/IDM Client
    • FreeIPA/IDM Setup Part
    • Linux FreeIPA/IDM Client Setup

FreeIPA

As typical CentOS is dead (yes there is CentOS Stream available but its not a RHEL clone) I have two options here. Rocky Linux and Alma Linux. I will use the latter as it seems more popular and more up to date. In this guide the FreeIPA/IDM server will hosted on the Alma Linux 8.6 system.

To make things easier I installed that Alma Linux 8.6 with single 20GB / root on the /dev/sda1 partition. No separate /boot. No LVM. Just good old plain fucking simple single raw partition for everything. Seems no one does it these days πŸ™‚

[root@idm ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   20G  0 disk
└─sda1   8:1    0   20G  0 part /

FreeIPA Requirements

The minimum hardware requirements for installing FreeIPA server are as follows.

RAM: 4GB
CPU: 2
HDD: 10GB
DNS: fully qualified domain name for FreeIPA
     must be resolvable from DNS server configured in system

For this installation I have used the 10.0.0.0/24 network.

The FreeIPA/IDM server will get the 10.0.0.40 IP.

The FreeIPA/IDM Linux client rhlike.vercorp.org will get the 10.0.0.41 IP.

The FreeIPA/IDM FreeBSD client fbsd.vercorp.org will get the 10.0.0.42 IP.

The FreeIPA/IDM FreeBSD client fbsdjail.vercorp.org will get the 10.0.0.43 IP.

For lack of better ideas I have used vercorp.org/VERCORP.ORG as domain/realm names and idm.vercorp.org as the FreeIPA/IDM hostname.

Details of FreeIPA/IDM idm.vercorp.org system below.

      IP: 10.0.0.40/24
      GW: 10.0.0.1
     DNS: 1.1.1.1
hostname: idm.vercorp.org
  domain: vercorp.org
   realm: VERCORP.ORG

FreeBSD fbsd.vercorp.org system.

      IP: 10.0.0.42/24
      GW: 10.0.0.1
hostname: fbsd.vercorp.org

FreeBSD Jail fbsdjail.vercorp.org system.

      IP: 10.0.0.43/24
      GW: 10.0.0.1
hostname: fbsdjail.vercorp.org

If you are curious what is hidden in the 10.0.0.42 IP – then its a typical Alma Linux that I first used to try if the FreeIPA/IDM works at all πŸ™‚

FreeIPA Setup

Because Anaconda is far from being a usable installer – this is how the only enp0s3 interface config looks like after manual intervention.

[root@idm ~]# cat /etc/sysconfig/network-scripts/ifcfg-enp0s3
NAME=enp0s3
DEVICE=enp0s3
TYPE=Ethernet
BOOTPROTO=none
UUID=b49cd1ab-d3eb-421d-b408-c052acc077da
ONBOOT=yes
IPADDR=10.0.0.40
NETMASK=255.255.255.0
GATEWAY=10.0.0.1
IPV6INIT=no
DNS1=1.1.1.1
PROXY_METHOD=none
BROWSER_ONLY=no
DEFROUTE=yes
IPV4_FAILURE_FATAL=no

Before we will go into setup procedures – we will update that Alma Linux system.

[root@idm ~]# yum update -y
[root@idm ~]# reboot

After the reboot we will disable the IPv6 stack for main interface (enp0s3) as FreeIPA installer has some problem with it. We do not need IPv6 here anyway so …

[root@idm ~]# cat << EOF >> /etc/sysctl.conf
# DISABLE IPv6 FOR MAIN enp0s3 INTERFACE
net.ipv6.conf.enp0s3.disable_ipv6=1
EOF

Lets set our FreeIPA/IDM hostname if we missed that at the Anaconda installer part. We will also setup the system time zone.

[root@idm ~]# hostnamectl set-hostname idm.vercorp.org

[root@idm ~]# hostnamectl
   Static hostname: idm.vercorp.org
         Icon name: computer-vm
           Chassis: vm
        Machine ID: b8bfb8bcc23147eb9cc7b62c72a09c32
           Boot ID: 06158ef430d9467d959076ab4396314e
    Virtualization: oracle
  Operating System: AlmaLinux 8.6 (Sky Tiger)
       CPE OS Name: cpe:/o:almalinux:almalinux:8::baseos
            Kernel: Linux 4.18.0-372.26.1.el8_6.x86_64
      Architecture: x86-64

[root@idm ~]# timedatectl set-timezone Europe/Warsaw

[root@idm ~]# timedatectl set-local-rtc 0

[root@idm ~]#Β timedatectl
               Local time: Mon 2022-10-17 15:08:28 CEST
           Universal time: Mon 2022-10-17 13:08:28 UTC
                 RTC time: Sat 2022-10-15 00:28:10
                Time zone: Europe/Warsaw (CEST, +0200)
System clock synchronized: yes
              NTP service: inactive
          RTC in local TZ: no

Lets add the system IP and name to the /etc/hosts file now.

[root@idm ~]# echo "$( hostname -i | awk '{print $NF}' )   $( hostname ) $( hostname -s )" >> /etc/hosts

[root@idm ~]# grep idm /etc/hosts
10.0.0.40   idm.vercorp.org idm

[root@idm ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.0.0.40   idm.vercorp.org idm

We need to enable the FreeIPA/IDM module in yum(8).

[root@idm ~]# yum module list idm
Last metadata expiration check: 0:00:31 ago on Tue 18 Oct 2022 01:02:51 PM CEST.
AlmaLinux 8 - AppStream
Name  Stream      Profiles                                  Summary
idm   DL1         adtrust, client, common [d], dns, server  The Red Hat Enterprise Linux Identity Management system module
idm   client [d]  common [d]                                RHEL IdM long term support client module

Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled

[root@idm ~]# yum module enable idm:DL1 -y
Last metadata expiration check: 0:01:06 ago on Tue 18 Oct 2022 01:02:51 PM CEST.
Dependencies resolved.
=====================================================================================================
 Package                 Architecture           Version                  Repository              Size
=====================================================================================================
Enabling module streams:
 389-ds                                         1.4
 httpd                                          2.4
 idm                                            DL1
 pki-core                                       10.6
 pki-deps                                       10.6

Transaction Summary
=====================================================================================================

Complete!

Some additional step needed.

[root@idm ~]# yum distro-sync
Last metadata expiration check: 0:10:07 ago on Mon 17 Oct 2022 03:14:32 PM CEST.
Dependencies resolved.
Nothing to do.
Complete!

We will now install FreeIPA/IDM with DNS as this setup is the most simplistic one. We focus on FreeBSD part here in that article.

[root@idm ~]# yum install -y bind-utils chrony nc
[root@idm ~]# yum module install idm:DL1/dns -y

One can use the ‘interactive’ installer and answer ‘by hand’ for all the asked questions – but to be honest I prefer to type my command once and make it ‘happen’ altogether without my time wasted.

As you probably guessed – we will use the unattended mode for the FreeIPA/IDM installer.

[root@idm ~]# ipa-server-install \
    --domain vercorp.org \
    --realm VERCORP.ORG \
    --reverse-zone=0.0.10.in-addr.arpa. \
    --no-forwarders \
    --no-ntp \
    --setup-dns \
    --ds-password    [password] \
    --admin-password [password] \
    --unattended

Checking DNS domain 0.0.10.in-addr.arpa., please wait ...

The log file for this installation can be found in /var/log/ipaserver-install.log
==============================================================================
This program will set up the IPA Server.
Version 4.9.8

This includes:
  * Configure a stand-alone CA (dogtag) for certificate management
  * Create and configure an instance of Directory Server
  * Create and configure a Kerberos Key Distribution Center (KDC)
  * Configure Apache (httpd)
  * Configure DNS (bind)
  * Configure SID generation
  * Configure the KDC to enable PKINIT

Excluded by options:
  * Configure the NTP client (chronyd)

Warning: skipping DNS resolution of host idm.vercorp.org
Checking DNS domain vercorp.org., please wait ...
Checking DNS domain 0.0.10.in-addr.arpa., please wait ...
Checking DNS domain 0.0.10.in-addr.arpa., please wait ...
Using reverse zone(s) 0.0.10.in-addr.arpa.
Trust is configured but no NetBIOS domain name found, setting it now.

The IPA Master Server will be configured with:
Hostname:       idm.vercorp.org
IP address(es): 10.0.0.40
Domain name:    vercorp.org
Realm name:     VERCORP.ORG

The CA will be configured with:
Subject DN:   CN=Certificate Authority,O=VERCORP.ORG
Subject base: O=VERCORP.ORG
Chaining:     self-signed

BIND DNS server will be configured to serve IPA domain with:
Forwarders:       No forwarders
Forward policy:   only
Reverse zone(s):  0.0.10.in-addr.arpa.

Disabled p11-kit-proxy
Configuring directory server (dirsrv). Estimated time: 30 seconds
  [1/41]: creating directory server instance
Validate installation settings ...
Create file system structures ...
Perform SELinux labeling ...
Create database backend: dc=vercorp,dc=org ...
Perform post-installation tasks ...
  [2/41]: tune ldbm plugin
  [3/41]: adding default schema
  [4/41]: enabling memberof plugin
  [5/41]: enabling winsync plugin
  [6/41]: configure password logging
  [7/41]: configuring replication version plugin
  [8/41]: enabling IPA enrollment plugin
  [9/41]: configuring uniqueness plugin
  [10/41]: configuring uuid plugin
  [11/41]: configuring modrdn plugin
  [12/41]: configuring DNS plugin
  [13/41]: enabling entryUSN plugin
  [14/41]: configuring lockout plugin
  [15/41]: configuring topology plugin
  [16/41]: creating indices
  [17/41]: enabling referential integrity plugin
  [18/41]: configuring certmap.conf
  [19/41]: configure new location for managed entries
  [20/41]: configure dirsrv ccache and keytab
  [21/41]: enabling SASL mapping fallback
  [22/41]: restarting directory server
  [23/41]: adding sasl mappings to the directory
  [24/41]: adding default layout
  [25/41]: adding delegation layout
  [26/41]: creating container for managed entries
  [27/41]: configuring user private groups
  [28/41]: configuring netgroups from hostgroups
  [29/41]: creating default Sudo bind user
  [30/41]: creating default Auto Member layout
  [31/41]: adding range check plugin
  [32/41]: creating default HBAC rule allow_all
  [33/41]: adding entries for topology management
  [34/41]: initializing group membership
  [35/41]: adding master entry
  [36/41]: initializing domain level
  [37/41]: configuring Posix uid/gid generation
  [38/41]: adding replication acis
  [39/41]: activating sidgen plugin
  [40/41]: activating extdom plugin
  [41/41]: configuring directory to start on boot
Done configuring directory server (dirsrv).
Configuring Kerberos KDC (krb5kdc)
  [1/10]: adding kerberos container to the directory
  [2/10]: configuring KDC
  [3/10]: initialize kerberos container
  [4/10]: adding default ACIs
  [5/10]: creating a keytab for the directory
  [6/10]: creating a keytab for the machine
  [7/10]: adding the password extension to the directory
  [8/10]: creating anonymous principal
  [9/10]: starting the KDC
  [10/10]: configuring KDC to start on boot
Done configuring Kerberos KDC (krb5kdc).
Configuring kadmin
  [1/2]: starting kadmin
  [2/2]: configuring kadmin to start on boot
Done configuring kadmin.
Configuring ipa-custodia
  [1/5]: Making sure custodia container exists
  [2/5]: Generating ipa-custodia config file
  [3/5]: Generating ipa-custodia keys
  [4/5]: starting ipa-custodia
  [5/5]: configuring ipa-custodia to start on boot
Done configuring ipa-custodia.
Configuring certificate server (pki-tomcatd). Estimated time: 3 minutes
  [1/29]: configuring certificate server instance
  [2/29]: stopping certificate server instance to update CS.cfg
  [3/29]: backing up CS.cfg
  [4/29]: Add ipa-pki-wait-running
  [5/29]: secure AJP connector
  [6/29]: reindex attributes
  [7/29]: exporting Dogtag certificate store pin
  [8/29]: disabling nonces
  [9/29]: set up CRL publishing
  [10/29]: enable PKIX certificate path discovery and validation
  [11/29]: authorizing RA to modify profiles
  [12/29]: authorizing RA to manage lightweight CAs
  [13/29]: Ensure lightweight CAs container exists
  [14/29]: Ensuring backward compatibility
  [15/29]: starting certificate server instance
  [16/29]: configure certmonger for renewals
  [17/29]: requesting RA certificate from CA
  [18/29]: publishing the CA certificate
  [19/29]: adding RA agent as a trusted user
  [20/29]: configure certificate renewals
  [21/29]: Configure HTTP to proxy connections
  [22/29]: updating IPA configuration
  [23/29]: enabling CA instance
  [24/29]: importing IPA certificate profiles
  [25/29]: migrating certificate profiles to LDAP
  [26/29]: adding default CA ACL
  [27/29]: adding 'ipa' CA entry
  [28/29]: configuring certmonger renewal for lightweight CAs
  [29/29]: deploying ACME service
Done configuring certificate server (pki-tomcatd).
Configuring directory server (dirsrv)
  [1/3]: configuring TLS for DS instance
  [2/3]: adding CA certificate entry
  [3/3]: restarting directory server
Done configuring directory server (dirsrv).
Configuring ipa-otpd
  [1/2]: starting ipa-otpd
  [2/2]: configuring ipa-otpd to start on boot
Done configuring ipa-otpd.
Configuring the web interface (httpd)
  [1/22]: stopping httpd
  [2/22]: backing up ssl.conf
  [3/22]: disabling nss.conf
  [4/22]: configuring mod_ssl certificate paths
  [5/22]: setting mod_ssl protocol list
  [6/22]: configuring mod_ssl log directory
  [7/22]: disabling mod_ssl OCSP
  [8/22]: adding URL rewriting rules
  [9/22]: configuring httpd
Nothing to do for configure_httpd_wsgi_conf
  [10/22]: setting up httpd keytab
  [11/22]: configuring Gssproxy
  [12/22]: setting up ssl
  [13/22]: configure certmonger for renewals
  [14/22]: publish CA cert
  [15/22]: clean up any existing httpd ccaches
  [16/22]: enable ccache sweep
  [17/22]: configuring SELinux for httpd
  [18/22]: create KDC proxy config
  [19/22]: enable KDC proxy
  [20/22]: starting httpd
  [21/22]: configuring httpd to start on boot
  [22/22]: enabling oddjobd
Done configuring the web interface (httpd).
Configuring Kerberos KDC (krb5kdc)
  [1/1]: installing X509 Certificate for PKINIT
Done configuring Kerberos KDC (krb5kdc).
Applying LDAP updates
Upgrading IPA:. Estimated time: 1 minute 30 seconds
  [1/10]: stopping directory server
  [2/10]: saving configuration
  [3/10]: disabling listeners
  [4/10]: enabling DS global lock
  [5/10]: disabling Schema Compat
  [6/10]: starting directory server
  [7/10]: upgrading server
  [8/10]: stopping directory server
  [9/10]: restoring configuration
  [10/10]: starting directory server
Done.
Restarting the KDC
dnssec-validation yes
Configuring DNS (named)
  [1/12]: generating rndc key file
  [2/12]: adding DNS container
  [3/12]: setting up our zone
  [4/12]: setting up reverse zone
  [5/12]: setting up our own record
  [6/12]: setting up records for other masters
  [7/12]: adding NS record to the zones
  [8/12]: setting up kerberos principal
  [9/12]: setting up named.conf
created new /etc/named.conf
created named user config '/etc/named/ipa-ext.conf'
created named user config '/etc/named/ipa-options-ext.conf'
created named user config '/etc/named/ipa-logging-ext.conf'
  [10/12]: setting up server configuration
  [11/12]: configuring named to start on boot
  [12/12]: changing resolv.conf to point to ourselves
Done configuring DNS (named).
Restarting the web server to pick up resolv.conf changes
Configuring DNS key synchronization service (ipa-dnskeysyncd)
  [1/7]: checking status
  [2/7]: setting up bind-dyndb-ldap working directory
  [3/7]: setting up kerberos principal
  [4/7]: setting up SoftHSM
  [5/7]: adding DNSSEC containers
  [6/7]: creating replica keys
  [7/7]: configuring ipa-dnskeysyncd to start on boot
Done configuring DNS key synchronization service (ipa-dnskeysyncd).
Restarting ipa-dnskeysyncd
Restarting named
Updating DNS system records
Configuring SID generation
  [1/8]: creating samba domain object
  [2/8]: adding admin(group) SIDs
  [3/8]: adding RID bases
  [4/8]: updating Kerberos config
'dns_lookup_kdc' already set to 'true', nothing to do.
  [5/8]: activating sidgen task
  [6/8]: restarting Directory Server to take MS PAC and LDAP plugins changes into account
  [7/8]: adding fallback group
  [8/8]: adding SIDs to existing users and groups
This step may take considerable amount of time, please wait..
Done.
Configuring client side components
This program will set up IPA client.
Version 4.9.8

Using existing certificate '/etc/ipa/ca.crt'.
Client hostname: idm.vercorp.org
Realm: VERCORP.ORG
DNS Domain: vercorp.org
IPA Server: idm.vercorp.org
BaseDN: dc=vercorp,dc=org

Configured /etc/sssd/sssd.conf
Systemwide CA database updated.
Adding SSH public key from /etc/ssh/ssh_host_ed25519_key.pub
Adding SSH public key from /etc/ssh/ssh_host_ecdsa_key.pub
Adding SSH public key from /etc/ssh/ssh_host_rsa_key.pub
SSSD enabled
Configured /etc/openldap/ldap.conf
Configured /etc/ssh/ssh_config
Configured /etc/ssh/sshd_config
Configuring vercorp.org as NIS domain.
Client configuration complete.
The ipa-client-install command was successful

==============================================================================
Setup complete

Next steps:
  1. You must make sure these network ports are open:
    TCP Ports:
      * 80, 443: HTTP/HTTPS
      * 389, 636: LDAP/LDAPS
      * 88, 464: kerberos
      * 53: bind
    UDP Ports:
      * 88, 464: kerberos
      * 53: bind

  2. You can now obtain a kerberos ticket using the command: 'kinit admin'
     This ticket will allow you to use the IPA tools (e.g., ipa user-add)
     and the web user interface.
  3. Kerberos requires time synchronization between clients
     and servers for correct operation. You should consider enabling chronyd.

Be sure to back up the CA certificates stored in /root/cacert.p12
These files are required to create replicas. The password for these
files is the Directory Manager password
The ipa-server-install command was successful
[root@idm ~]#

Seems that all went well and now we have our FreeIPA/IDM installed.

Lets check several things.

[root@idm ~]# ipactl status
Directory Service: RUNNING
krb5kdc Service: RUNNING
kadmin Service: RUNNING
named Service: RUNNING
httpd Service: RUNNING
ipa-custodia Service: RUNNING
pki-tomcatd Service: RUNNING
ipa-otpd Service: RUNNING
ipa-dnskeysyncd Service: RUNNING
ipa: INFO: The ipactl command was successful

[root@idm ~]# systemctl list-unit-files | grep ipa | grep service
ipa-ccache-sweep.service                   disabled
ipa-custodia.service                       disabled
ipa-dnskeysyncd.service                    disabled
ipa-healthcheck.service                    disabled
ipa-ods-exporter.service                   disabled
ipa-otpd@.service                          static
ipa.service                                enabled

Seems to be installed and working.

What about the /etc/sssd/sssd.conf config.

[root@idm ~]# cat /etc/sssd/sssd.conf
[domain/vercorp.org]

id_provider = ipa
ipa_server_mode = True
ipa_server = idm.vercorp.org
ipa_domain = vercorp.org
ipa_hostname = idm.vercorp.org
auth_provider = ipa
chpass_provider = ipa
access_provider = ipa
cache_credentials = True
ldap_tls_cacert = /etc/ipa/ca.crt
krb5_store_password_if_offline = True
[sssd]
services = nss, pam, ifp, ssh, sudo

domains = vercorp.org
[nss]
homedir_substring = /home
memcache_timeout = 600

[pam]

[sudo]

[autofs]

[ssh]

[pac]

[ifp]
allowed_uids = ipaapi, root

[session_recording]

There is also /etc/ssh/ssh_config.d/04-ipa.conf file …

[root@idm ~]# cat /etc/ssh/ssh_config.d/04-ipa.conf
# IPA-related configuration changes to ssh_config
#
PubkeyAuthentication yes
GlobalKnownHostsFile /var/lib/sss/pubconf/known_hosts
#VerifyHostKeyDNS yes

# assumes that if a user does not have shell (/sbin/nologin),
# this will return nonzero exit code and proxy command will be ignored
Match exec true
  ProxyCommand /usr/bin/sss_ssh_knownhostsproxy -p %p %h

For some reason we need to manually enable and start the Apache HTTP server.

[root@idm ~]# systemctl enable --now httpd

You can now access the FreeIPA/IDM at your browser on the http://idm.vercorp.org address. If you use the http://10.0.0.40 IP then you will be redirected to the http://idm.vercorp.org address so make sure you have added that host to your local /etc/hosts file.

FreeIPA-login-page

FreeIPA-login

On the second screen you will see that I have already created the vermaden user.

FreeBSD Client

UPDATE: Newer instructions for FreeBSD 13.2-RELEASE are available at the Connect FreeBSD 13.2 to FreeIPA/IDM article.

We will get straight into the point. After having FreeBSD 13.1-RELEASE installed in the most ‘default’ way in the bsdinstall(8) installer – the Auto ZFS road – we will now fetch the up to date FreeBSD Ports tree with portsnap(8) tool.

This is the main /etc/rc.conf config file.

# cat /etc/rc.conf
hostname="fbsd"
ifconfig_vtnet0="inet 10.0.0.42 netmask 255.255.255.0"
defaultrouter="10.0.0.1"
sshd_enable="YES"
moused_enable="YES"
dumpdev="AUTO"
zfs_enable="YES"
syslogd_flags="-ss"
sssd_enable="YES"

FreeBSD Packages

We need to have FreeBSD Ports tree.

# portsnap auto

Lets check what is the current default SAMBA version on FreeBSD.

# grep -i samba /usr/ports/Mk/*default*
        PYTHON2 PYTHON3 RUBY RUST SAMBA SSL TCLTK VARNISH
SAMBA_DEFAULT?=         4.12

To omit a lot of pointless compilation I will first install all precompiled packages – that would also install needed dependencies. Then we will rebuild just the several needed packages.

# pkg install krb5 sudo cyrus-sasl cyrus-sasl-gssapi pam_mkhomedir openldap26-client samba412

Settings in the /etc/make.conf file.

# cat /etc/make.conf
# USE /usr/ports/obj PLACE
WRKDIRPREFIX=${PORTSDIR}/obj

OPTIONS_UNSET=       DOCS EXAMPLES DEBUG X11
OPTIONS_UNSET+=      DBUS GSSAPI_BASE GSSAPI_HEIMDAL
OPTIONS_SET+=        GSSAPI_MIT
WITH_GSSAPI=         yes
WANT_OPENLDAP_SASL=  yes

Lets configure the needed ports.

# \
for I in /usr/ports/security/sudo \
         /usr/ports/security/sssd \
         /usr/ports/security/krb5 \
         /usr/ports/security/cyrus-sasl2-gssapi \
         /usr/ports/security/pam_mkhomedir \
         /usr/ports/net/openldap26-client
do
  make -C ${I} rmconfig
done

# \
for I in /usr/ports/security/sudo \
         /usr/ports/security/sssd \
         /usr/ports/security/krb5 \
         /usr/ports/security/cyrus-sasl2-gssapi \
         /usr/ports/security/pam_mkhomedir \
         /usr/ports/net/openldap26-client
do
  make -C ${I} config-recursive
done

The curses(3X) selection will look more or less like these below.

=> security/sudo | OPTIONS___________________________________________________________________________
[x] AUDIT              Enable BSM audit support
[ ] DISABLE_AUTH       Do not require authentication by default
[ ] DISABLE_ROOT_SUDO  Do not allow root to run sudo
[ ] DOCS               Build and/or install documentation
[ ] EXAMPLES           Build and/or install examples
[ ] INSULTS            Enable insults on failures
[x] LDAP               LDAP protocol support
[ ] NLS                Native Language Support
[ ] NOARGS_SHELL       Run a shell if no arguments are given
[ ] OPIE               Enable one-time passwords (no PAM support)
[ ] PAM                Pluggable authentication module support
[ ] PYTHON             Enable python plugin support
[x] SSSD               Enable SSSD backend support.
=> security/sudo | Kerberos 5 Authentication (no PAM support)
( ) GSSAPI_BASE        GSSAPI support via base system (needs Kerberos)
( ) GSSAPI_HEIMDAL     GSSAPI support via security/heimdal
(*) GSSAPI_MIT         GSSAPI support via security/krb5


=> security/sssd | OPTIONS___________________________________________________________________________
[ ] DOCS  Build and/or install documentation
[x] SMB   Install IPA and AD providers (requires Samba4)


=> security/cyrus-sasl2-gssapi | OPTIONS_____________________________________________________________
( ) GSSAPI_BASE     GSSAPI support via base system (needs Kerberos)
( ) GSSAPI_HEIMDAL  GSSAPI support via security/heimdal
(*) GSSAPI_MIT      GSSAPI support via security/krb5


=> net/openldap26-client | OPTIONS___________________________________________________________________
[ ] DEBUG   Build with debugging support
[ ] DOCS    Build and/or install documentation
[ ] FETCH   Enable fetch(3) support
[x] GSSAPI  With GSSAPI support


=> security/krb5 | OPTIONS___________________________________________________________________________
[ ] DNS_FOR_REALM  Enable DNS lookups for Kerberos realm names
[ ] EXAMPLES       Build and/or install examples
[x] KRB5_HTML      Install krb5 HTML documentation
[x] KRB5_PDF       Install krb5 PDF documentation
[x] LDAP           LDAP protocol support
[ ] LMDB           OpenLDAP Lightning Memory-Mapped Database support
[ ] NLS            Native Language Support
=> security/krb5 | Command Line Editing for kadmin and ktutil
(*) READLINE       Command line editing via libreadline
( ) LIBEDIT        Command line editing via libedit

We can now check what options have been saved.

# cat /var/db/ports/security_sudo-sssd/options
_OPTIONS_READ=sudo-sssd-1.9.11p3
_FILE_COMPLETE_OPTIONS_LIST=AUDIT DISABLE_AUTH DISABLE_ROOT_SUDO DOCS EXAMPLES INSULTS LDAP NLS NOARGS_SHELL OPIE PAM PYTHON SSSD GSSAPI_BASE GSSAPI_HEIMDAL GSSAPI_MIT
OPTIONS_FILE_SET+=AUDIT
OPTIONS_FILE_SET+=GSSAPI_MIT
OPTIONS_FILE_SET+=LDAP
OPTIONS_FILE_SET+=NLS
OPTIONS_FILE_SET+=SSSD
OPTIONS_FILE_UNSET+=DISABLE_AUTH
OPTIONS_FILE_UNSET+=DISABLE_ROOT_SUDO
OPTIONS_FILE_UNSET+=DOCS
OPTIONS_FILE_UNSET+=EXAMPLES
OPTIONS_FILE_UNSET+=GSSAPI_BASE
OPTIONS_FILE_UNSET+=GSSAPI_HEIMDAL
OPTIONS_FILE_UNSET+=INSULTS
OPTIONS_FILE_UNSET+=NOARGS_SHELL
OPTIONS_FILE_UNSET+=OPIE
OPTIONS_FILE_UNSET+=PAM
OPTIONS_FILE_UNSET+=PYTHON

# cat /var/db/ports/security_sssd/options
_OPTIONS_READ=sssd-1.16.5_6
_FILE_COMPLETE_OPTIONS_LIST=DOCS SMB
OPTIONS_FILE_UNSET+=DOCS
OPTIONS_FILE_SET+=SMB

# cat /var/db/ports/security_cyrus-sasl2/options
_OPTIONS_READ=cyrus-sasl-2.1.28
_FILE_COMPLETE_OPTIONS_LIST=ALWAYSTRUE AUTHDAEMOND DOCS KEEP_DB_OPEN  OBSOLETE_CRAM_ATTR OBSOLETE_DIGEST_ATTR  SASLDB_IN_VAR BDB1 BDB GDBM LMDB ANONYMOUS CRAM DIGEST LOGIN NTLM OTP PLAIN SCRAM
OPTIONS_FILE_SET+=ANONYMOUS
OPTIONS_FILE_SET+=AUTHDAEMOND
OPTIONS_FILE_SET+=BDB1
OPTIONS_FILE_SET+=CRAM
OPTIONS_FILE_SET+=DIGEST
OPTIONS_FILE_SET+=LOGIN
OPTIONS_FILE_SET+=NTLM
OPTIONS_FILE_SET+=OBSOLETE_CRAM_ATTR
OPTIONS_FILE_SET+=OBSOLETE_DIGEST_ATTR
OPTIONS_FILE_SET+=OTP
OPTIONS_FILE_SET+=PLAIN
OPTIONS_FILE_SET+=SCRAM
OPTIONS_FILE_UNSET+=ALWAYSTRUE
OPTIONS_FILE_UNSET+=BDB
OPTIONS_FILE_UNSET+=DOCS
OPTIONS_FILE_UNSET+=GDBM
OPTIONS_FILE_UNSET+=KEEP_DB_OPEN
OPTIONS_FILE_UNSET+=LMDB
OPTIONS_FILE_UNSET+=SASLDB_IN_VAR

# cat /var/db/ports/net_openldap26-client/options
_OPTIONS_READ=openldap26-client-2.6.3
_FILE_COMPLETE_OPTIONS_LIST=DEBUG DOCS FETCH GSSAPI
OPTIONS_FILE_SET+=GSSAPI
OPTIONS_FILE_UNSET+=DEBUG
OPTIONS_FILE_UNSET+=DOCS
OPTIONS_FILE_UNSET+=FETCH

# cat /var/db/ports/security_krb5/options
# This file is auto-generated by 'make config'.
# Options for krb5-1.20
_OPTIONS_READ=krb5-1.20
_FILE_COMPLETE_OPTIONS_LIST=DNS_FOR_REALM EXAMPLES KRB5_HTML KRB5_PDF LDAP LMDB NLS READLINE LIBEDIT
OPTIONS_FILE_UNSET+=DNS_FOR_REALM
OPTIONS_FILE_UNSET+=EXAMPLES
OPTIONS_FILE_SET+=KRB5_HTML
OPTIONS_FILE_SET+=KRB5_PDF
OPTIONS_FILE_SET+=LDAP
OPTIONS_FILE_UNSET+=LMDB
OPTIONS_FILE_SET+=NLS
OPTIONS_FILE_SET+=READLINE
OPTIONS_FILE_UNSET+=LIBEDIT

… and build them.

# \
for I in /usr/ports/security/sudo \
         /usr/ports/security/sssd \
         /usr/ports/security/krb5
         /usr/ports/security/cyrus-sasl2-gssapi \
         /usr/ports/security/pam_mkhomedir \
         /usr/ports/net/openldap26-client \
do
  make -C ${I} build
done

… unsinstall them and create their packages.

# \
for I in /usr/ports/security/sudo \
         /usr/ports/security/sssd \
         /usr/ports/security/krb5
         /usr/ports/security/cyrus-sasl2-gssapi \
         /usr/ports/security/pam_mkhomedir \
         /usr/ports/net/openldap26-client \
do
  make -C ${I} deinstall package
done

After some time we have our built packages.

# find /usr/ports/obj/ -name \*.pkg
/usr/ports/obj/usr/ports/lang/perl5.32/work/perl-5.32.1/symbian/ext/Moped/Msg/Msg.pkg
/usr/ports/obj/usr/ports/security/pam_mkhomedir/work/pkg/pam_mkhomedir-0.2.pkg
/usr/ports/obj/usr/ports/security/cyrus-sasl2-gssapi/work/pkg/cyrus-sasl-gssapi-2.1.28.pkg
/usr/ports/obj/usr/ports/security/krb5/work/pkg/krb5-1.20.pkg
/usr/ports/obj/usr/ports/security/sudo/work/pkg/sudo-1.9.11p3.pkg
/usr/ports/obj/usr/ports/security/sssd/work-default/pkg/sssd-1.16.5_6.pkg
/usr/ports/obj/usr/ports/net/openldap26-client/work/pkg/openldap26-client-2.6.3.pkg

In the future I need to add some short guide to build them regularly with Synth or Poudriere πŸ™‚

Now we need to install these packages in quite nontypical way. One by one – in specified order. It will not be needed it we would have a separate additional pkg(8) repository with Poudriere build packages.

Our packages:

# ls -1 *.pkg
cyrus-sasl-gssapi-2.1.28.pkg
krb5-1.20.pkg
openldap26-client-2.6.3.pkg
pam_mkhomedir-0.2.pkg
sssd-smb4-1.16.5_6.pkg
sudo-sssd-1.9.11p3.pkg

… and their install process.

# pkg install -y c-ares

# pkg add sssd-smb4-1.16.5_6.pkg

# pkg install -y cyrus-sasl-gssapi-2.1.28.pkg
(...)
New packages to be INSTALLED:
        cyrus-sasl: 2.1.28
        cyrus-sasl-gssapi: 2.1.28
        krb5: 1.20
(...)

# pkg delete -f -y krb5
(...)
Installed packages to be REMOVED:
        krb5: 1.20
(...)

# pkg add krb5-1.20.pkg

# pkg install -y sssd

# pkg add sudo-sssd-1.9.11p3.pkg

# pkg delete -f -y sssd
(...)
Installed packages to be REMOVED:
        sssd: 1.16.5_6
(...)

# pkg install ding-libs ldb21 nspr nss pcre samba412

# pkg add sssd-smb4-1.16.5_6.pkg

FreeBSD Setup

Create needed dirs.

# mkdir -p \
    /usr/local/etc/ipa \
    /var/log/sssd \
    /var/run/sss/private \
    /var/db/sss

Set system hostname.

# hostname fbsd.vercorp.org

# hostname
fbsd.vercorp.org

Fetch the FreeIPA/IDM certificate.

# fetch -o /usr/local/etc/ipa/ca.crt http://10.0.0.40/ipa/config/ca.crt

FreeIPA/IDM Setup Part

We need to execute several instructions on the FreeIPA/IDM to connect FreeBSD client to it.

Its adding the A and PTR records in DNS for the 10.0.0.42 address and adding the fbsd.vercorp.org host.

We also need to generate the key for our fbsd.vercorp.org system.

[root@idm ~]# kinit admin
Password for admin@VERCORP.ORG:

[root@idm ~]# ipa dnsrecord-add vercorp.org fbsd --a-rec=10.0.0.42 --a-create-reverse
  Record name: fbsd
  A record: 10.0.0.42

[root@idm ~]# ipa host-add fbsd.vercorp.org
-----------------------------
Added host "fbsd.vercorp.org"
-----------------------------
  Host name: fbsd.vercorp.org
  Principal name: host/fbsd.vercorp.org@VERCORP.ORG
  Principal alias: host/fbsd.vercorp.org@VERCORP.ORG
  Password: False
  Keytab: False
  Managed by: fbsd.vercorp.org

[root@idm ~]# ipa-getkeytab -s idm.vercorp.org -p host/fbsd.vercorp.org@VERCORP.ORG -k /root/fbsd.vercorp.org.keytab
Keytab successfully retrieved and stored in: /root/fbsd.vercorp.org.keytab

Now we need to get ‘our’ key from FreeIPA/IDM server … along with proper /etc/hosts file.

# scp root@10.0.0.40:/root/fbsd.vercorp.org.keytab /usr/local/etc/ipa/krb5.keytab

# cat << EOF > /etc/hosts
::1              localhost localhost.my.domain
127.0.0.1        localhost localhost.my.domain
10.0.0.40        idm.vercorp.org  idm
10.0.0.42        fbsd.vercorp.org fbsd
EOF

Now the /usr/local/etc/openldap/ldap.conf file.

# cat << EOF > /usr/local/etc/openldap/ldap.conf
BASE        dc=org,dc=vercorp
URI         ldap://idm.vercorp.org/
#SIZELIMIT  12
#TIMELIMIT  15
#DEREF      never
SASL_MECH   GSSAPI
SASL_REALM  VERCORP.ORG
ssl         start_tls
TLS_CACERT  /usr/local/etc/ipa/ca.crt
EOF

… and /etc/krb5.conf file.

# cat << EOF > /etc/krb5.conf
[libdefaults]
  default_realm = VERCORP.ORG
  default_keytab_name = FILE:/usr/local/etc/ipa/krb5.keytab
  default_tkt_enctypes = aes256-cts des-cbc-crc aes128-cts arcfour-hmac
  default_tgs_enctypes = aes256-cts des-cbc-crc aes128-cts arcfour-hmac
  dns_lookup_realm = false
  dns_lookup_kdc = false
  rdns = false
  ticket_lifetime = 24h
  forwardable = yes

[realms]
  VERCORP.ORG = {
    kdc = idm.vercorp.org:88
    master_kdc = idm.vercorp.org:88
    admin_server = idm.vercorp.org:749
    default_domain = vercorp.org
    pkinit_anchors = FILE:/usr/local/etc/ipa/ca.crt
}

[domain_realm]
  .vercorp.org = VERCORP.ORG
  vercorp.org = VERCORP.ORG

[logging]
  kdc = FILE:/var/log/krb5/krb5kdc.log
  admin_server = FILE:/var/log/krb5/kadmin.log
  kadmin_local = FILE:/var/log/krb5/kadmin_local.log
  default = FILE:/var/log/krb5/krb5lib.log
EOF

… and /usr/local/etc/sssd/sssd.conf file.

# cat << EOF > /usr/local/etc/sssd/sssd.conf

[domain/vercorp.org]
# debug_level = 9
cache_credentials = True
krb5_store_password_if_offline = True
krb5_realm = VERCORP.ORG
ipa_domain = vercorp.org
id_provider = ipa
auth_provider = ipa
access_provider = ipa
ipa_hostname = fbsd.vercorp.org
chpass_provider = ipa
ipa_server = _srv_, idm.vercorp.org
ldap_tls_cacert = /usr/local/etc/ipa/ca.crt
krb5_keytab = /usr/local/etc/ipa/krb5.keytab

[sssd]
services = nss, pam, ssh, sudo
config_file_version = 2
domains = vercorp.org

[nss]
filter_users = root,toor
homedir_substring = /usr/home/%u

[pam]

[sudo]
# debug_level = 0x3ff0

[ssh]
EOF

# chmod 600 /usr/local/etc/sssd/sssd.conf

FreeBSD have user account under /usr/home to make sure /home also points there.

# ln -s /usr/home /home

The automatic startup of sssd(8) daemon (not to confuse with sshd(8)) needs to be also configured.

# sysrc sssd_enable=YES
# service sssd start

We also need to configure /etc/nsswitch.conf file.

# cp /etc/nsswitch.conf /etc/nsswitch.conf.BCK

# diff -u /etc/nsswitch.conf.BCK /etc/nsswitch.conf
--- /etc/nsswitch.conf.BCK      2022-10-24 20:10:09.163251000 +0200
+++ /etc/nsswitch.conf  2022-10-24 20:10:57.207406000 +0200
@@ -2,15 +2,17 @@
 # nsswitch.conf(5) - name service switch configuration file
 # $FreeBSD$
 #
-group: compat
+group: files sss
 group_compat: nis
 hosts: files dns
-netgroup: compat
+# netgroup: compat
 networks: files
-passwd: compat
+passwd: files sss
 passwd_compat: nis
 shells: files
 services: compat
 services_compat: nis
 protocols: files
 rpc: files
+sudoers: sss files
+netgroup: files

The final /etc/nsswitch.conf file looks as follows.

# cat /etc/nsswitch.conf
#
# nsswitch.conf(5) - name service switch configuration file
# $FreeBSD$
#
group: files sss
group_compat: nis
hosts: files dns
# netgroup: compat
networks: files
passwd: files sss
passwd_compat: nis
shells: files
services: compat
services_compat: nis
protocols: files
rpc: files
sudoers: sss files
netgroup: files

Now the /etc/pam.d/system file.

# cp /etc/pam.d/system /root/etc---pam.d---system.BCK

# diff -u  /root/etc---pam.d---system.BCK /etc/pam.d/system
--- /root/etc---pam.d---system.BCK      2022-10-24 20:13:05.546657000 +0200
+++ /etc/pam.d/system   2022-10-24 20:16:36.722666000 +0200
@@ -7,19 +7,23 @@
 # auth
 auth           sufficient      pam_opie.so             no_warn no_fake_prompts
 auth           requisite       pam_opieaccess.so       no_warn allow_local
-#auth          sufficient      pam_krb5.so             no_warn try_first_pass
+auth           sufficient      pam_krb5.so             no_warn try_first_pass
 #auth          sufficient      pam_ssh.so              no_warn try_first_pass
+auth           sufficient      /usr/local/lib/pam_sss.so       use_first_pass
 auth           required        pam_unix.so             no_warn try_first_pass nullok

 # account
 #account       required        pam_krb5.so
 account                required        pam_login_access.so
 account                required        pam_unix.so
+account                required        /usr/local/lib/pam_sss.so       ignore_unknown_user ignore_authinfo_unavail

 # session
 #session       optional        pam_ssh.so              want_agent
 session                required        pam_lastlog.so          no_fail
+session                required        /usr/local/lib/pam_mkhomedir.so mode=0700

 # password
 #password      sufficient      pam_krb5.so             no_warn try_first_pass
+password       sufficient      /usr/local/lib/pam_sss.so       use_authtok
 password       required        pam_unix.so             no_warn try_first_pass

The final /etc/pam.d/system file looks as follows.

# cat /etc/pam.d/system
#
# $FreeBSD$
#
# System-wide defaults
#

# auth
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so       no_warn allow_local
auth            sufficient      pam_krb5.so             no_warn try_first_pass
#auth           sufficient      pam_ssh.so              no_warn try_first_pass
auth            sufficient      /usr/local/lib/pam_sss.so       use_first_pass
auth            required        pam_unix.so             no_warn try_first_pass nullok

# account
#account        required        pam_krb5.so
account         required        pam_login_access.so
account         required        pam_unix.so
account         required        /usr/local/lib/pam_sss.so       ignore_unknown_user ignore_authinfo_unavail

# session
#session        optional        pam_ssh.so              want_agent
session         required        pam_lastlog.so          no_fail
session         required        /usr/local/lib/pam_mkhomedir.so mode=0700

# password
#password       sufficient      pam_krb5.so             no_warn try_first_pass
password        sufficient      /usr/local/lib/pam_sss.so       use_authtok
password        required        pam_unix.so             no_warn try_first_pass

Now its time for /etc/pam.d/sshd file.

# cp /etc/pam.d/sshd /root/etc---pam.d---sshd.BCK

# diff -u /root/etc---pam.d---sshd.BCK /etc/pam.d/sshd
--- /root/etc---pam.d---sshd.BCK        2022-10-24 20:17:34.063630000 +0200
+++ /etc/pam.d/sshd     2022-10-24 20:19:16.165810000 +0200
@@ -7,8 +7,9 @@
 # auth
 auth           sufficient      pam_opie.so             no_warn no_fake_prompts
 auth           requisite       pam_opieaccess.so       no_warn allow_local
-#auth          sufficient      pam_krb5.so             no_warn try_first_pass
+auth           sufficient      pam_krb5.so             no_warn try_first_pass
 #auth          sufficient      pam_ssh.so              no_warn try_first_pass
+auth           sufficient      /usr/local/lib/pam_sss.so       use_first_pass
 auth           required        pam_unix.so             no_warn try_first_pass

 # account
@@ -16,11 +17,14 @@
 #account       required        pam_krb5.so
 account                required        pam_login_access.so
 account                required        pam_unix.so
+account                required        /usr/local/lib/pam_sss.so       ignore_unknown_user ignore_authinfo_unavail

 # session
 #session       optional        pam_ssh.so              want_agent
 session                required        pam_permit.so
+session                required        /usr/local/lib/pam_mkhomedir.so mode=0700

 # password
 #password      sufficient      pam_krb5.so             no_warn try_first_pass
+password       sufficient      /usr/local/lib/pam_sss.so       use_authtok
 password       required        pam_unix.so             no_warn try_first_pass

Final /etc/pam.d/sshd file below.

# cat /etc/pam.d/sshd
#
# $FreeBSD$
#
# PAM configuration for the "sshd" service
#

# auth
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so       no_warn allow_local
auth            sufficient      pam_krb5.so             no_warn try_first_pass
#auth           sufficient      pam_ssh.so              no_warn try_first_pass
auth            sufficient      /usr/local/lib/pam_sss.so       use_first_pass
auth            required        pam_unix.so             no_warn try_first_pass

# account
account         required        pam_nologin.so
#account        required        pam_krb5.so
account         required        pam_login_access.so
account         required        pam_unix.so
account         required        /usr/local/lib/pam_sss.so       ignore_unknown_user ignore_authinfo_unavail

# session
#session        optional        pam_ssh.so              want_agent
session         required        pam_permit.so
session         required        /usr/local/lib/pam_mkhomedir.so mode=0700

# password
#password       sufficient      pam_krb5.so             no_warn try_first_pass
password        sufficient      /usr/local/lib/pam_sss.so       use_authtok
password        required        pam_unix.so             no_warn try_first_pass

Small modification in the /etc/ssh/ssh_config and /etc/ssh/sshd_config files.

# cat << EOF >> /etc/ssh/ssh_config
GSSAPIAuthentication yes
EOF

# cat << EOF >> /etc/ssh/sshd_config
GSSAPIAuthentication yes
UsePAM yes
EOF

Finish Setup with Web Browser in FreeIPA/IDM Page

Visit the https://idm.vercorp.org/ipa/ui/#/e/hbacrule/details/freebsd page.

Next create the HBAC Rule named freebsd as showed below.

idm-1-hbac-rules-menu

idm-2-hbac-rules-freebsd

idm-3-hbac-rules-freebsd-details

… and the Sudo Rule named freebsd name.

idm-4-sudo-rules-menu

idm-5-sudo-rules-freebsd

idm-6-sudo-rules-freebsd-details

FreeBSD FreeIPA Login Test

After all these time consuming and pointless instructions we can now finally try to login to our FreeBSD client.

% ssh -l vermaden 10.0.0.42
(vermaden@10.0.0.42) Password:
Last login: Mon Oct 24 21:06:36 2022 from 10.0.0.3
FreeBSD 13.1-RELEASE releng/13.1-n250148-fc952ac2212 GENERIC

Welcome to FreeBSD!

Release Notes, Errata: https://www.FreeBSD.org/releases/
Security Advisories:   https://www.FreeBSD.org/security/
FreeBSD Handbook:      https://www.FreeBSD.org/handbook/
FreeBSD FAQ:           https://www.FreeBSD.org/faq/
Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/
FreeBSD Forums:        https://forums.FreeBSD.org/

Documents installed with the system are in the /usr/local/share/doc/freebsd/
directory, or can be installed later with:  pkg install en-freebsd-doc
For other languages, replace "en" with a language code like de or fr.

Show the version of FreeBSD installed:  freebsd-version ; uname -a
Please include that output and any error messages when posting questions.
Introduction to manual pages:  man man
FreeBSD directory layout:      man hier

To change this login announcement, see motd(5).
You can upload the dmesg of your system to help developers get an overview of commonly
used hardware and peripherals for FreeBSD. Use the curl package to upload it like this:
curl -v -d "nickname=$USER" -d "description=FreeBSD/$(uname -m) on \
$(kenv smbios.system.maker) $(kenv smbios.system.product)" -d "do=addd" \
--data-urlencode 'dmesg@/var/run/dmesg.boot' http://dmesgd.nycbug.org/index.cgi

vermaden@fbsd:~ $ :> ~/.hushlogin

vermaden@fbsd:~ $ id
uid=1408200003(vermaden) gid=1408200000(admins) groups=1408200000(admins)

vermaden@fbsd:~ $ pwd
/home/vermaden

vermaden@fbsd:~ $ grep vermaden /etc/passwd /etc/group
vermaden@fbsd:~ $

vermaden@fbsd:~ $ getent passwd vermaden
vermaden:*:1408200003:1408200000:vermaden vermaden:/home/vermaden:/bin/sh

vermaden@fbsd:~ $ sudo su -
Password for vermaden@VERCORP.ORG:

root@fbsd:~ # logout

vermaden@fbsd:~ $ sudo -i

root@fbsd:~ #

Strange … seems to work properly πŸ™‚

FreeBSD Jail as FreeIPA/IDM Client

As ‘full’ FreeBSD system is able to connect to the FreeIPA/IDM server we will not configure FreeBSD Jail to do the same.

The FreeIPA/IDM FreeBSD client fbsdjail.vercorp.orgwill get the 10.0.0.43 IP.

Basic FreeBSD Jail Preparations

Lets setup the Jail for a start.

# mkdir -p /jail/fbsdjail /jail/BASE

# cd /jail/fbsdjail

# fetch -o /jail/BASE/13.1-RELEASE-base.txz https://download.freebsd.org/ftp/releases/amd64/13.1-RELEASE/base.txz

# tar --unlink -xvf ../BASE/13.1-RELEASE-base.txz

# cat << EOF > /etc/jail.conf
# GLOBAL
  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  exec.clean;
  exec.consolelog = "/var/log/jail_${name}_console.log";
  mount.devfs;
  host.hostname = ${name};
  path = /jail/${name};

# JAILS
  fbsdjail {
    ip4.addr = 10.0.0.43;
    host.hostname = fbsdjail.vercorp.org;
    interface = wlan0;
    allow.raw_sockets;
    allow.sysvipc;
  }
EOF

# cat /etc/resolv.conf | tee /jail/fbsdjail/etc/resolv.conf
nameserver 10.0.0.1

# echo 10.0.0.43 fbsdjail.vercorp.org fbsdjail | tee -a /etc/hosts | tee -a /jail/fbsdjail/etc/hosts

# cat /etc/hosts /jail/fbsdjail/etc/hosts
10.0.0.43 fbsdjail.vercorp.org fbsdjail
10.0.0.43 fbsdjail.vercorp.org fbsdjail

# cat << EOF > /jail/fbsdjail/etc/rc.conf
# DAEMONS | yes
  syslogd_flags="-ss"
  sshd_enable=YES

# OTHER
  clear_tmp_enable=YES
  clear_tmp_X=YES
  dumpdev=NO
  update_motd=NO
EOF

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

# grep latest /jail/fbsdjail/etc/pkg/FreeBSD.conf
  url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",

Now we can start our FreeBSD Jail.

# service jail onestart fbsdjail
Starting jails: fbsdjail.

# jls
   JID  IP Address      Hostname                      Path
     1  10.0.0.43       fbsdjail.vercorp.org          /jail/fbsdjail

# jls -v
   JID  Hostname                      Path
        Name                          State
        CPUSetID
        IP Address(es)
     1  fbsdjail.vercorp.org          /jail/fbsdjail
        fbsdjail                      ACTIVE
        3
        10.0.0.43

# jexec fbsdjail

root@fbsdjail:/ #

Our FreeBSD Jail works. Lets move to next steps.

Configure FreeBSD Jail to Connect to FreeIPA/IDM Server

I could not repaste all of the instructions above – the ones that we used for a ‘full’ FreeBSD system – but the same applies to a FreeBSD Jail. πŸ™‚

This means that earlier Basic FreeBSD Jail Preparations section covers all that is needed in case of ‘full’ FreeBSD versus FreeBSD Jail when it comes to the FreeIPA/IDM connection.

Linux FreeIPA/IDM Client

This article is not about Linux client – which is pretty straight-forward to connect to the FreeIPA/IDM server – but for the completness of the topic – here are the instructions I used to attach Alma Linux to the FreeIPA/IDM server.

Linux rhlike.vercorp.org system.

      IP: 10.0.0.41/24
      GW: 10.0.0.1
hostname: rhlike.vercorp.org

First – install the @idm:client and sssd packages.

client # yum -y install @idm:client sssd

FreeIPA/IDM Setup Part

Now – as earlier with FreeBSD – the FreeIPA/IDM part comes to play.

[root@idm ~]# kinit admin
Password for admin@VERCORP.ORG:

[root@idm ~]# klist
Ticket cache: KCM:0
Default principal: admin@VERCORP.ORG

Valid starting       Expires              Service principal
10/19/2022 13:33:52  10/20/2022 13:11:28  krbtgt/VERCORP.ORG@VERCORP.ORG

[root@idm ~]# ipa user-find
---------------
2 users matched
---------------
  User login: admin
  Last name: Administrator
  Home directory: /home/admin
  Login shell: /bin/bash
  Principal alias: admin@VERCORP.ORG, root@VERCORP.ORG
  UID: 1896600000
  GID: 1896600000
  Account disabled: False

  User login: vermaden
  First name: vermaden
  Last name: vermaden
  Home directory: /home/vermaden
  Login shell: /bin/sh
  Principal name: vermaden@VERCORP.ORG
  Principal alias: vermaden@VERCORP.ORG
  Email address: vermaden@vercorp.org
  UID: 1896600003
  GID: 1000
  Account disabled: False
----------------------------
Number of entries returned 2
----------------------------

[root@idm ~]# id vermaden
uid=1408200003(vermaden) gid=1408200000(admins) groups=1408200000(admins)

[root@idm ~]# ipa dnsrecord-add vercorp.org rhlike --a-rec 10.0.0.41
  Record name: rhlike
  A record: 10.0.0.41

We are done on the FreeIPA/IDM side.

Linux FreeIPA/IDM Client Setup

We will now continue our work on the Linux client.

client # echo "10.0.0.40   idm.vercorp.org"    >> /etc/hosts

client # echo "10.0.0.41   rhlike.vercorp.org" >> /etc/hosts

client # hostnamectl set-hostname rhlike.vercorp.org

client # cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.0.0.40   idm.vercorp.org
10.0.0.41   rhlike.vercorp.org

client # ipa-client-install --uninstall

client # ipa-client-install \
           --hostname=rhlike.vercorp.org \
           --mkhomedir \
           --server=idm.vercorp.org \
           --domain vercorp.org \
           --realm VERCORP.ORG

This program will set up IPA client.
Version 4.9.8

Autodiscovery of servers for failover cannot work with this configuration.
If you proceed with the installation, services will be configured to always access the discovered server for all operations and will not fail over to other servers in case of failure.
Proceed with fixed values and no DNS discovery? [no]: yes
Do you want to configure chrony with NTP server or pool address? [no]: no
Client hostname: rhlike.vercorp.org
Realm: VERCORP.ORG
DNS Domain: vercorp.org
IPA Server: idm.vercorp.org
BaseDN: dc=vercorp,dc=org

Continue to configure the system with these values? [no]: yes
Synchronizing time
No SRV records of NTP servers found and no NTP server or pool address was provided.
Using default chrony configuration.
Attempting to sync time with chronyc.
Time synchronization was successful.
User authorized to enroll computers: admin
Password for admin@VERCORP.ORG:
Successfully retrieved CA cert
    Subject:     CN=Certificate Authority,O=VERCORP.ORG
    Issuer:      CN=Certificate Authority,O=VERCORP.ORG
    Valid From:  2022-10-18 14:52:50
    Valid Until: 2042-10-18 14:52:50

Enrolled in IPA realm VERCORP.ORG
Created /etc/ipa/default.conf
Configured /etc/sssd/sssd.conf
Configured /etc/krb5.conf for IPA realm VERCORP.ORG
Systemwide CA database updated.
Hostname (rhlike.vercorp.org) does not have A/AAAA record.
Failed to update DNS records.
Missing A/AAAA record(s) for host rhlike.vercorp.org: 10.0.0.41.
Missing reverse record(s) for address(es): 10.0.0.41.
Adding SSH public key from /etc/ssh/ssh_host_ed25519_key.pub
Adding SSH public key from /etc/ssh/ssh_host_ecdsa_key.pub
Adding SSH public key from /etc/ssh/ssh_host_rsa_key.pub
Could not update DNS SSHFP records.
SSSD enabled
Configured /etc/openldap/ldap.conf
Configured /etc/ssh/ssh_config
Configured /etc/ssh/sshd_config
Configuring vercorp.org as NIS domain.
Client configuration complete.
The ipa-client-install command was successful

client # reboot

Now we will test how it goes with login against the FreeIPA/IDM server.

laptop % ssh -l vermaden 10.0.0.41
(vermaden@10.0.0.41) Password:
(vermaden@10.0.0.41) Password expired. Change your password now.
Current Password:
(vermaden@10.0.0.41) New password:
(vermaden@10.0.0.41) Retype new password:
Last failed login: Wed Oct 19 00:47:57 CEST 2022 from 10.0.0.3 on ssh:notty
There was 1 failed login attempt since the last successful login.
/usr/bin/id: cannot find name for group ID 1000

[vermaden@rhlike ~]$ w
 00:48:16 up 29 min,  2 users,  load average: 0.22, 0.13, 0.16
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    10.0.0.3         00:40   58.00s  0.03s  0.03s -bash
vermaden pts/1    10.0.0.3         00:48    0.00s  0.02s  0.01s w

[vermaden@rhlike ~]$ sudo su -

[root@rhlike ~]# getent passwd admin
admin:*:1896600000:1896600000:Administrator:/home/admin:/bin/bash

[root@rhlike ~]# getent passwd vermaden
vermaden:*:1896600003:1000:vermaden vermaden:/home/vermaden:/bin/sh

Seems to work at least OK πŸ™‚

I do not have anything more to add to this guide.

If you have – then please let me know in comments πŸ™‚

Regards.

EOF

FreeBSD Cope with WiFi Fuckup

I really wanted the name of this article does not sound dramatically but I was not able to invent any other title … none the less the wireless/WiFi topic can be problematic on the FreeBSD land. Its a known feat of FreeBSD that is does its job best at the server room and that laptop/desktop based configurations tend to need some ‘love’ to be usable. The worst thing of that part is lack of WiFi kernel drivers at all or slower then possible speed like 802.11g on 802.11n capable chips – often as old as 11 years old Intel Ultimate-N 6300 450Mbps card that runs only at 802.11g speed on FreeBSD. The aim of this article is to show you the alternatives and possibilities when it comes to wireless and/or WiFi problems that you may encounter on FreeBSD UNIX system.

Replace Unsupported Hardware

Assuming your laptop came with WiFi card that is not supported at all by FreeBSD drivers – one of the options can be to replace the mSATA or M.2 card with the supported one. It may be difficult because of BIOS blacklisting/whitelisting so there is possibility that it may be needed to flash your laptop/system with a hacked BIOS that does not have this blacklisting/whitelisting and allows ALL possible chips to be installed into it. This may be sometimes not possible of course and it really PITA that some/many manufacturers create such blacklisting/whitelisting bullshit without any reasonable reason then money heist.

Tiny USB WiFi Dongle

If your WiFi card is not supported at all and its not possible to replace it with mSATA and/or M.2 WiFi chip then you may use some tiny USB WiFi dongle with – for example – Realtek RTL8188CUS chip – which is supported on FreeBSD. While the chip itself is 802.11n 150Mbps capable the FreeBSD drivers only support 802.11g mode on it – but its still better then none connectivity at all.

Such tiny USB dongle can be shown below.

realtek

The more in depth article about that Realtek RTL8188CUS chip is available here –Β Realtek RTL8188CUS – USB 802.11n WiFi ReviewΒ – in one of my earlier articles.

Smartphone USB Tethering

One of the alternative possibilities is to use your smartphone with USB cable to provide the Internet connection. The main benefit of this approach is that you probably always have your smartphone with you anyway. The only additional needed/missing part is the USB cable (which is not that a problem anyway once you order it). This comes handy in more then one way. The first and obvious way is to just use that smartphone with USB cable attached to your FreeBSD to provide Internet connection no matter if that smartphone provides that connection using LTE/4G connection or WiFi connection to some WiFi hotspot. Another reason why this setup comes handy is when you have your WiFi chipset supported … and still are not able to connect to some WiFi hotspot. Recently I was at my buddy’s home where he had open WiFi network available. My phone connected to it without a problem but FreeBSD with 11 years old Intel 6300 card … was not able to connect to it no matter what. To be precise the wpa_supplicant(8) showed the CTRL-EVENT-CONNECTED status but the dhclient was not able to get the IP for some reason. This is where my smartphone came handy as it was able to connect to that open unencrypted network and FreeBSD used it by the USB tethering method. Below I will show you how to use the USB tethering on FreeBSD.

The first thing is to attach your smartphone by USB cable to your FreeBSD system. After you have done that you will need to configure your smartphone to enable USB tethering. Below you will find such configuration for Android smartphone.

usb-tethering

After you have chosen these settings you wull see the ue0 device in your ifconfig(8) interfaces listing.

% ifconfig
em0: flags=8c22<broadcast,oactive,simplex,multicast> metric 0 mtu 1500
        options=481249b<rxcsum,txcsum,vlan_mtu,vlan_hwtagging,vlan_hwcsum,lro,wol_magic,vlan_hwfilter,nomap>
        ether f0:de:f1:68:bc:ab
        media: Ethernet autoselect
        status: no carrier
        nd6 options=29<performnud,ifdisabled,auto_linklocal>
lo0: flags=8049<up,loopback,running,multicast> metric 0 mtu 16384
        options=680003<rxcsum,txcsum,linkstate,rxcsum_ipv6,txcsum_ipv6>
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
        inet 127.0.0.1/8
        groups: lo
        nd6 options=21<performnud,auto_linklocal>
vboxnet0: flags=8802<broadcast,simplex,multicast> metric 0 mtu 1500
        ether 0a:00:27:00:00:00
        media: Ethernet autoselect
        status: active
        nd6 options=29<performnud,ifdisabled,auto_linklocal>
ue0: flags=8802<broadcast,simplex,multicast> metric 0 mtu 1500
        ether 02:2a:71:6a:08:01
        nd6 options=29<performnud,ifdisabled,auto_linklocal>

The next (and last) step is to use dhclient(8) daemon to acquire the IP address using DHCP. Here is the command I used.

# dhclient ue0
DHCPDISCOVER on ue0 to 255.255.255.255 port 67 interval 4
DHCPOFFER from 192.168.73.209
DHCPREQUEST on ue0 to 255.255.255.255 port 67
DHCPACK from 192.168.73.209
bound to 192.168.73.16 -- renewal in 1799 seconds.

You can now test your connection with ping(8) command for example.

% ping -c 1 e.pl
PING e.pl (195.46.43.240): 56 data bytes
64 bytes from 195.46.43.240: icmp_seq=0 ttl=53 time=65.638 ms

--- e.pl ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 65.638/65.638/65.638/0.000 ms

You can now see that you got the needed IP address on your ue0 interface.

% ifconfig ue0
ue0: flags=8843<up,broadcast,running,simplex,multicast> metric 0 mtu 1500
        ether 02:2a:71:6a:08:01
        inet 192.168.73.16/24 broadcast 192.168.73.255
        nd6 options=29<performnud,ifdisabled,auto_linklocal>
</performnud,ifdisabled,auto_linklocal></up,broadcast,running,simplex,multicast>

This means that your Internet connection over USB tethering is functional.

One of the additional benefits of this approach is that USB connection also provides the power to your smartphone – which means that you only need one cable for both Internet connection and power for the smartphone device.

Mobile Router with RJ45 Cable

There is also additional option available and it provides similar possibilities to USB tethering – its using some mobile wireless router what would connect to LTE/4G network or some WiFi access point and will also have RJ45 socket so you will be able to connect to it with the RJ45 port on your laptop/desktop FreeBSD system.

You can find many such devices in real cheap price such as Overmax 3G or RAVPower RP-WD03-BK to name some. They come in $15 to $30 price range which should be marked as affordable for most people. Additional bonus from these devices is that they also serve as powerbank function. Also being powered its not needed to also power them up all the time – as the often allow for whole day function on the battery itself.

The Overmax 3G device is shown below.

overmax-3g

The RAVPower RP-WD03-BK is shown below.

ravpower

Bhyve wifibox VM

There is also one additional way to get your WiFi connection – use bhyve(8) virtualization. With wifibox you will deploy Linux VM – and use Linux wireless drivers for the card that may be unsupported on FreeBSD system. It works because of bhyve(8) PCI passthrough feature. You just pass the WiFi card directly to Linux VM.

The biggest advantage of wifibox is that everything is shipped in single FreeBSD package that can be easily installed and removed. You will just have to add wifibox package with pkg(8) – the FreeBSD package manager.

It also comes with rc(8) service script that automatically starts that Linux VM upon FreeBSD boot – and stops gracefully on shutdown.

Summary

What works best? To be honest its still more convenient to use builtin WiFi chip even at slower 802.11g speeds then using any other methods described in this article. Next one is using the mobile router with RJ45 cable. The next one (and somewhat slower one) is the USB tethering method – but while slower I was able to successfully post that article using it – so its not a major drawback. At the least one is using the wifibox way. Its generally up to You – what makes less PITA for you.

I of course hope that WiFi will get some more love in the FreeBSD land and that such ‘strange’ methods would not be needed to ‘just’ connect to the Internet.

Regards.