Realtek RTL8125 network interface driver for FreeBSD

Realtek RTL8125 is a network interface card, that is integrated on modern mid to high range motherboards, such as Asus Prime with 12th and 13th generation Intel CPUs. RTL8125 is not supported by the default Realtek driver, that is loaded by the FreeBSD base system during boot. This presents several issues on a host with no Internet access. With a tip from a brilliant user on Discord, I was able to discover this work-around.

RTL8125 is supported by a non-default Realtek driver, that was written by Realtek for FreeBSD, but not adopted into the main driver, because of differences in coding standards. The driver is in ports as “realtek-re-kmod”. If the host does not have a connection to Internet, then this port has to be fetched on another host and then transferred via USB storage or alternative medium.

# fetch http://pkg.freebsd.org/FreeBSD:14:amd64/release_2/All/realtek-re-kmod-1100.00_1.pkg

The package can not be installed, because the host would still need Internet for that, because of package management. The driver can be extracted and manually placed in the directory for boot kernel modules.

# tar zxf realtek-re-kmod1100.00_1.pkg /boot/modules/if_re.ko
# mv boot/modules/if_re.ko /boot/modules/

The driver needs to load during boot, while it is key to succes, that the “name” paramenter is set to the new driver. If this is omitted, then it will not work, because the old driver is loaded from “/boot/kernel”.

# vi /boot/loader.conf
if_re_load="YES"
if_re_name="/boot/modules/if_re.ko"

This will initialize the Realtek network interface card and DHCP for the network interface can be configured.

# vi /etc/rc.conf
ifconfig_re0="DHCP"

Reboot.

# reboot

The complete procedure:

# dmesg
# gpart show
# gpart destroy -F /dev/da0
# gpart create -s mbr /dev/da0
# gpart add -t fat32 /dev/da0
# gpart show
# newfs_msdos -L REALTEK -F 32 /dev/da0s1
# mount -t msdos /dev/da0s1 /mnt
# cd /mnt
# fetch http://pkg.freebsd.org/FreeBSD:14:amd64/release_2/All/realtek-re-kmod-1100.00_1.pkg
# sync
# cd
# umount /mnt
# mount -t msdos /dev/da0s1 /mnt
# cp /mnt/*.pkg .
# umount /mnt
# tar zxf realtek-re-kmod1100.00_1.pkg /boot/modules/if_re.ko
# mv boot/modules/if_re.ko /boot/modules/
# vi /boot/loader.conf
if_re_load="YES"
if_re_name="/boot/modules/if_re.ko"
# vi /etc/rc.conf
ifconfig_re0="DHCP"
# reboot

References.

Reject Failed SPF with spfmilter for Sendmail on FreeBSD

What is spfmilter?

spfmilter is a Sender Policy Framework (SPF) mail filter module for Sendmail on FreeBSD. spfmilter makes Sendmail reject mail, that has been sent from a mail server, that is not allowed by the policy for the domain. spfmilter s the other half of the framework.

Example of an CEO scam email, that is being contructed with false sender header fields in an Alpine mail client. DKIM authentication and SPF authorization prevents this kind of domain abuse. This can be implemented with an SPF TXT record for BIND DNS and OpenDKIM milter for Sendmail with a DKIM TXT record for BIND DNS on FreeBSD
Example of an CEO scam email, that is being contructed with false sender header fields in an Alpine mail client. Sender Policy Framework (SPF) prevents this kind of domain abuse.

Install spfmilter for Sendmail on FreeBSD

Search for spfmilter in the package repository.

# pkg search spf
spfmilter-2.001_2 SPF milter for sendmail

Install the spfmilter.

# pkg install spfmilter
The following 2 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
libspf2: 1.2.11_2
spfmilter: 2.001_2
144 KiB to be downloaded.

Configure spfmilter.

# nano /etc/mail/

Configure FreeBSD to run spfmilter as a service

Configure spfmilter as a service in FreeBSD. This is documented on the official website of spfmilter.

# service -l | grep spf
spfmilter
# nano /etc/rc.conf
spfmilter_enable="YES"
spfmilter_socket="unix:/var/run/spfmilter.sock"
# service spfmilter start
Starting spfmilter.
# grep spfmilter /var/log/maillog
Nov 17 13:37:55 foo spfmilter[34074]: spfmilter 2.001 with libspf2-1.2.11 starting

Configure Sendmail to use spfmilter

Configure Sendmail to use spfmilter. This is documented on the official website of spfmilter.

# cd /etc/mail
# cp `hostname`.mc `date -I`-`hostname`.mc
# nano `hostname`.mc
INPUT_MAIL_FILTER(`spfmilter',`S=unix:/var/run/spfmilter.sock')
# make
/usr/bin/m4 -D_CF_DIR_=/usr/share/sendmail/cf/ /usr/share/sendmail/cf/m4/cf.m4 foo.micski.dk.mc > foo.micski.dk.cf
# make install
install -m 444 foo.micski.dk.cf /etc/mail/sendmail.cf
install -m 444 foo.micski.dk.submit.cf /etc/mail/submit.cf
# service sendmail restart
Stopping sendmail.
Starting sendmail.
# tail /var/log/maillog | grep sm-m
Nov 17 13:37:08 foobar sm-mta[37327]: starting daemon (8.18.1): SMTP+queueing@00:30:00
Nov 17 13:37:08 foobar sm-msp-queue[37341]: starting daemon (8.18.1): queueing@00:30:00

Test spfmilter

If regular email works after the installation, it is time to test the spfmilter.

In this example, I will try to forge an email to appear being from Microsoft, that has an SPF. It gets rejected by the spfmilter.

$ telnet foo.micski.dk 587
220 foo.micski.dk ESMTP Sendmail 8.18.1/8.18.1; Sun, 17 Nov 2024 13:37:51 +0100 (CET)
HELO microsoft.com
250 foo.micski.dk Hello [13.37.13.37], pleased to meet you
MAIL From:<>
550 5.7.1 <>... fail

The rejection by spfmilter can be confirmed by the mail log.

# tail /var/log/maillog
Nov 17 13:37:56 foo sm-mta[38143]: 4AGNbZ2E038143: milter=spfmilter, action=helo, continue
Nov 17 13:38:28 foo sm-mta[38143]: 4AGNbZ2E038143: Milter: sender:
Nov 17 13:38:28 foo spfmilter[34074]: rejecting mail from [13.37.13.37] - fail
Nov 17 13:38:28 foo sm-mta[38143]: 4AGNbZ2E038143: milter=spfmilter, action=mail, reject=550 5.7.1 fail
Nov 17 13:38:28 foo sm-mta[38143]: 4AGNbZ2E038143: Milter: from=, reject=550 5.7.1 fail

In generel, future rejects can be listed from the mail log.

# grep spfmilter /var/log/maillog | grep rejecting

References

Attribution and sharing.

Feel free to link to this guide, if you find it useful. Contributions and feedback is always appreciated.

Virtual Private Network (VPN) Server with OpenVPN and Easy-RSA on FreeBSD

In this example, I will create a virtual private network (VPN) server with OpenVPN and Easy-RSA on a FreeBSD VPS. OpenVPN clients, that connect to this VPN server, will then be able to connect to other OpenVPN clients, that are also connected to this VPN server. This is true, even though, the host of each client might not be able to do so otherwise due to carrier-grade network address translation (CG-NAT) or other network limitations. A client, can be any kind of host, such as a server, network device, personal computer workstation or smartphone mobile device. I will be using OpenVPN 2.6.12 and Easy-RSA 3.2.1 on FreeBSD 13.4. I will use the name “foobar” for the VPN server and “foobar-client” for OpenVPN clients.

       +------------------------------+
| VPN Server (Germany) |
|------------------------------|
| Internet IP: 123.123.123.123 |
| VPN IP: 10.8.0.1 |
+------------------------------+
|
|
| VPN Subnet: 10.8.0.0/24
----------------------------------------------
| |
| // Internet // |
DSL FW | | 5G CGNAT
+-----------------------+ +-----------------------+
| Client 1 (Copenhagen) | | Client 2 (Sweden) |
|-----------------------| |-----------------------|
| Local IP: 172.213.1.9 | | Local IP: 192.168.1.5 |
| VPN IP: 10.8.0.11 | | VPN IP: 10.8.0.12 |
+-----------------------+ +-----------------------+

Install OpenVPN and Easy-RSA on the VPN server.

OpenVPN is an open source virtual private network (VPN) solution, that provides secure connections and virtual networks on Internet. It uses SSL and TLS protocols for encryption, which ensures secure data transmission between clients and servers on the virtual network. OpenVPN supports a range of configurations, such as point-to-point and site-to-site setups. It can transmit over UDP or TCP through custom ports, which makes it flexible and capable of bypassing firewalls, network translations and other network limitations.

Easy-RSA is a command-line utility, that simplifies the process of creating and managing a public key infrastructure (PKI) for VPNs and other services, that rely on SSL and TLS certificates. It automates certificate generation, sets up a certificate authority (CA) and issues server and client certificates and does key management.

# pkg install -y openvpn easy-rsa

Create a CA and certificates for the VPN server with Easy-RSA.

Create the PKI with Easy-RSA. The PKI will consist of the CA, digital certificates, keys and revocation lists. The passphrase, that will be set for the CA, will be required, when creating certificates for clients.

# easyrsa init-pki
# easyrsa build-ca
# easyrsa build-server-full foobar nopass
# easyrsa gen-dh

Create a TLS-Auth key with OpenVPN.

A TLS-Auth key is a static, pre-shared key, that is used by OpenVPN to add an extra layer of security to the TLS handshake process. It authenticates the initial packets of the connection, which prevent unauthorized and malicious connections, such as denial-of-service attacks, from reaching the OpenVPN server.

# openvpn --genkey secret pki/ta.key

Copy certificates and TLS-Auth key to OpenVPN directory.

# mkdir /usr/local/etc/openvpn
# cp -pR pki/{ca.crt,dh.pem,issued,private,ta.key} /usr/local/etc/openvpn/
# chown -R openvpn:openvpn /usr/local/etc/openvpn
# chmod 600 /usr/local/etc/openvpn/*

Configure OpenVPN.

Configure basic settings, cryptographic settings and VPN network with client-to-client, IP address persistance and secure authentication.

# nano /usr/local/etc/openvpn/openvpn.conf
port 1194
proto udp
dev tun
ca ca.crt
cert issued/foobar.crt
key private/foobar.key
dh df.pem
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 10.8.0.0 255.255.255.0"
client-config-dir ccd
client-to-client
keepalive 10 120
tls-auth ta.key 0
data-ciphers AES-256-GCM:AES-256-CBC:AES-128-GCM:CHACHA20-POLY1305
cipher AES-256-CBC
auth SHA256
max-clients 5
user openvpn
group openvpn
persist-key
persist-tun
status openvpn-status.log
log openvpn.log
verb 3
mute 20
explicit-exit-notify 1

If you prefer, you can also begin with a copy of the sample configuration, that has comments.

# cp /usr/local/share/examples/openvpn/sample-config-files/server.conf /usr/local/etc/openvpn/openvpn.conf

Configure client configuration directory (CCD).

OpenVPN identifies each client by its common name (CN) from the client certificate. OpenVPN looks for a file with the same name in the client configuration directory (CCD). In this example, 2 OpenVPN client hosts, 1 and 2, will be assigned static IP addresses in the VPN.

# mkdir -m 700 /usr/local/etc/openvpn/ccd
# nano /usr/local/etc/openvpn/ccd/client-1
ifconfig-push 10.8.0.11 255.255.255.0
# nano /usr/local/etc/openvpn/ccd/client-2
ifconfig-push 10.8.0.12 255.255.255.0

Start OpenVPN server.

Configure FreeBSD to start OpenVPN at boot. Start OpenVPN.

# service openvpn enable
# service openvpn start
# tail -n 50 /usr/local/etc/openvpn/openvpn.log

Enable routing in FreeBSD.

# sysctl net.inet.ip.forwarding=1
# echo 'net.inet.ip.forwarding=1' >> /etc/sysctl.conf

Configure and start PF.

# ifconfig
# nano /etc/pf.conf
interface = "vtnet0"
network = "10.8.0.0/24"
set skip on lo
scrub in on $interface all fragment reassemble
nat on $interface from $network to any -> ($interface)
pass in on $interface proto udp from any to ($interface) port 1194
# service pflog enable
# service pf enable
# service pf start
# service pflog start

Disable TCP checksum offloading.

If TCP checksum offloading is not disabled, then the network interface card (NIC) may offload the calculation of checksums to the hardware, which can lead to a mismatch in checksums. This can lead to dropped connections and corrupt data.

# ifconfig vtnet0 -rxcsum -txcsum -rxcsum6 -txcsum6 -tso -lro 
# nano /etc/rc.conf
ifconfig_vtnet0="DHCP -rxcsum -txcsum -rxcsum6 -txcsum6 -tso -lro"

Create certificate for OpenVPN FreeBSD client with Easy-RSA.

# easyrsa build-client-full client-1 nopass
Private-Key and Public-Certificate-Request files created.
Your files are:
* req: /root/pki/reqs/client-1.req
* key: /root/pki/private/client-1.key
Certificate created at:
* /root/pki/issued/client-1.crt

Update certificates and keys in the OpenVPN directory.

# cp -pR pki/{issued,private} /usr/local/etc/openvpn/
# chown -R openvpn:openvpn /usr/local/etc/openvpn

Transfer certificates and keys to OpenVPN client.

In this example, I create a zip file, that contain the CA certificate, the TLS-Auth key, the client key and the client certificate. These certificates and keys will be needed for OpenVPN configuration on the OpenVPN client side.

# mkdir foobar-client
# cp pki/ca.crt foobar-client/foobar-ca.crt
# cp pki/ta.key foobar-client/foobar-ta.key
# cp pki/private/client-1.key foobar-client/
# cp pki/issued/client-1.crt foobar-client/
# zip -j foobar-client foobar-client/*

I recommend automizing this with a script, that takes the CN as an argument.

Install certificates and keys on OpenVPN FreeBSD client.

Extract the zip file, that contains the certificates and keys, that is needed for the OpenVPN configuration.

# unzip foobar-client.zip -d /usr/local/etc/openvpn
Archive: /root/foobar-client.zip
extracting: /usr/local/etc/openvpn/foobar-ca.crt
extracting: /usr/local/etc/openvpn/foobar-client-1.crt
extracting: /usr/local/etc/openvpn/foobar-client-1.key
extracting: /usr/local/etc/openvpn/foobar-ta.key
# chown openvpn:openvpn /usr/local/etc/openvpn/foobar-*

Create configuration file on OpenVPN FreeBSD client.

# nano /usr/local/etc/openvpn/foobar-client-1.ovpn
client
dev tun1
proto udp
remote 123.123.123.123 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca foobar-ca.crt
cert foobar-client-1.crt
key foobar-client-1.key
tls-auth foobar-ta.key 1
cipher AES-256-CBC
auth SHA256
remote-cert-tls server
verb 3

Start OpenVPN on the FreeBSD client.

# nano /etc/rc.conf
openvpn_enable="YES"
openvpn_configfile="/usr/local/etc/openvpn/foobar-client-1.ovpn"
openvpn_dir="/usr/local/etc/openvpn"
# service openvpn start

Confirm, that the tun interface is up.

# ifconfig tun1
tun1: flags=8043<UP,BROADCAST,RUNNING,MULTICAST> metric 0 mtu 1500
options=80000<LINKSTATE>
inet 10.8.0.11 netmask 0xffffff00 broadcast 10.8.0.255
groups: tun
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
Opened by PID 4885

Confirm, that the VPN server and other connected clients can be reached.

# ping 10.8.0.1
PING 10.8.0.1 (10.8.0.1): 56 data bytes
64 bytes from 10.8.0.1: icmp_seq=0 ttl=64 time=40.965 ms

Run multiple instances of OpenVPN on FreeBSD.

FreeBSD can run multiple instances of OpenVPN. This is done by assigning each one to a unique tun interface. An example of this could be one OpenVPN client for a privacy related VPN, such as Mullvad, and a business related VPN. Make sure, that each OpenVPN configuration will use different tun devices, different networks and different start scripts. The default start script in FreeBSD support multiple instances by linking the script to names, that can be applied in rc.conf.

In this example, I will run this OpenVPN client as an additional client.

# ln -s /usr/local/etc/rc.d/openvpn /usr/local/etc/rc.d/openvpn_foobar
# nano /etc/rc.conf
openvpn_foobar_enable="YES"
openvpn_foobar_configfile="/usr/local/etc/openvpn/foobar-client-1.ovpn"
openvpn_foobar_dir="/usr/local/etc/openvpn"
# service openvpn_foobar start

There will now be multiple tun devices with active networks.

# ifconfig

The routing table on a FreeBSD host with multiple OpenVPN clients.

In the following example, I used the built-in network analysis utility netstat to inspect the routing table on a FreeBSD host with multiple OpenVPN clients. The output is shown without resolving numeric addresses and ports to names. Traffic will be routed through the most direct and specific route. This is also known as the one with the longest prefix match. In the example, a connection to a client on 10.8.0.0/24 will be routed through tun1, and not tun0, even though Internet traffic on 0.0.0.0/1 will be routed through tun0. The same is true for connection to hosts on the LAN, because the 192.168.1.0/24 prefix is longer than the 128.0.0.0/1. Because the VPN subnet is directly reachable through the tun1 interface, there is no need to add an extra hop IP address as a gateway. The flags are used to indicate, if the link is up (U), and, if the link is a VPN gateway or default gateway (G).

# netstat -rn
Destination Gateway Flags Netif
127.0.0.1 link#2 UH lo0
192.168.1.0/24 link#1 U em0
10.8.0.0/24 link#4 U tun1
0.0.0.0/1 10.10.0.1 UGS tun0
128.0.0.0/1 10.10.0.1 UGS tun0
default 192.168.1.1 UGS em0

Solution: Static IP address for OpenVPN clients not working.

I noticed, that the assignment of static IP address for the OpenVPN clients did not work. The CCD had been defined. The client certificate CN matched the CCD filename in which the assigned IP address is defined. The syntax for IP address and subnet mask matched the documentation. I found, that the CCD directory had mode 600 and not 700. I fixed it and restarted OpenVPN. It worked.

# grep ccd /usr/local/etc/openvpn/openvpn.conf
client-config-dir ccd
# grep client-1 /usr/local/etc/openvpn/issued/client-1.crt
Subject: CN=client-1
# cat /usr/local/etc/openvpn/ccd/
ifconfig-push 10.8.0.11 255.255.255.0
# ls -ld /usr/local/etc/openvpn/ccd
drw------- 2 openvpn openvpn 6 Nov 12 13:37 /usr/local/etc/openvpn/ccd
# chmod 700 /usr/local/etc/openvpn/ccd
# service openvpn restart

More abount OpenVPN.

Attribution and sharing.

Feel free to link to this guide, if you find it useful. Contributions and feedback is always appreciated.

External USB SSD storage with FreeBSD GELI and ZFS

This is the procedure to prepare and configure external USB SSD storage for secure backup or storage with GELI encryption and ZFS on FreeBSD.

GELI, also known as GEOM ELI, is a built-in block-level disk encryption framework in FreeBSD. GELI provides encryption and integrity for data on storage devices, such as solid-state disks (SSDs), hard disk drives (HDDs), virtual disk drives, partitions and files.

How does GELI work?

When GELI encryption is applied to a file system for the first time, also known as initialized, the file system will be encrypted with a random master key. The master key is stored in the metadata of the GELI file system and it will remain unchanged. Instead, a user key will be used to decrypt the file system. The user key have an optional passphrase and an optional key file as its components. The user key can be changed and replaced as often as you want. I fact, up to 2 different user keys can be installed in slots. The GELI metadata, that contains the master key and the currently installed user keys, can be exported to a backup file and restored at a later time.

Identify the SSD device.

Attach the external storage and identify the device.

# dmesg
da0 at umass-sim0 bus 0 scbus7 target 0 lun 0
da0: <Seagate Performance 1337> Fixed Direct Access SPC-4 SCSI device
da0: Serial Number 1337XSCZ
da0: 400.000MB/s transfers
da0: 1907729MB (3907029167 512 byte sectors)
da0: quirks=0x2<NO_6_BYTE>

Create a key file for the user key.

In this example, I want a user key, that has both the passphrase and key file components. The key file can be created with the built-in FreeBSD utility dd. The size is not directly related to the data key length for the final encryption algorithm.

# dd if=/dev/random of=foobar.key bs=256 count=1
1+0 records in
1+0 records out
256 bytes transferred in 0.000037 secs (9560043 bytes/sec)

It is critical, that the encryption key foobar.key is stored in a safe place. I recommend, that it is named by the same name, that identifies the SSD. If the key is lost, then the encrypted data can not be decrypted.

Initialize GELI encryption.

The GELI encryption framework can now be initialized with the key file as an argument to the GELI utility. The GELI utility also creates the user key, that will consist of a passphrase and the key file foobar.key from before.

The sector size is set to 4096 bytes for better alignment with SSDs. The default encryption algorithm is AES-XTS. The data key length for the encryption algorithm is 256 bit. A backup of the metadata is written to the file foobar.eli. The utility will ask for a passphrase to be used as the passphrase component of the user key.

# geli init -s 4096 -K foobar.key -e aes-xts -l 256 -B foobar.eli /dev/da0
Enter new passphrase:
Reenter new passphrase:
Metadata backup for provider /dev/da0 can be found in foobar.eli
and can be restored with the following command:
# geli restore foobar.eli /dev/da0

The passphrase should be stored in a password manager or memorized. The passphrase and the encryption key are both components, that are necessary to have. If one of these components is lost, then the encrypted data can not be decrypted.

The metadata backup file foobar.eli should be stored in the same safe place as the key and can be used to restore the metadata of the SSD in the event of accidental overwrite, corruption, sector reallocation or drive failure. The metadata contain the master key and the user keys.

If changes are made to the user keys, such as passphrase or key file, a new backup of the metadata should be made.

Attach the GELI provider.

When the USB storage device has been connected, and FreeBSD has identified it, then the GELI utility can be used to decrypt the file system. This is known as attaching. In this example, the GELI provider is attached by supplying the passphrase and key file. The result is an accessible block device to the decrypted file system. The file system can now be formatted and used as normal.

# geli attach -k foobar.key /dev/da0
Enter passphrase:

Optionally partition the SSD.

The SSD storage device can be partioned with the built-in utility gpart and its ZFS partition type for FreeBSD. This can make the file system more compatible across systems. It is, however, not necessary. If the drive will only ever be used for ZFS, then partitioning is unnecessary. ZFS is designed to work seamlessly with whole disks. When given a whole disk, it uses it directly and optimizes the placement of metadata, labels and data alignment. ZFS can claim the entire drive, which will reduce the potential for error.

# gpart create -s gpt /dev/da0
# gpart add -t freebsd-zfs -l foobar /dev/da0

Create a ZFS pool.

In this example, ZFS will be used as the file system on the external storage device. Create a ZFS pool on the encrypted device. Optimize the pool for 4096 byte sectors, which is common for SSDs, as this setting aligns ZFS blocks with SSD sectors.

# zpool create -o ashift=12 zfoo /dev/da0.eli

If the device will be used for backup, you might want to enable LZ4 compression and disable access time updates for increased performance.

# zfs set compression=lz4 zfoo
# zfs set atime=off zfoo

Create ZFS datasets.

Create ZFS datasets in the pool as needed.

# zfs create zfoo/backup
# zfs create zfoo/backup/foo
# zfs create zfoo/backup/bar

Set the ZFS mountpoint.

Set the ZFS mountpoint.

# zfs set mountpoint=/mnt/zfoo zfoo

Export ZFS pool.

When the USB SSD is no longer to be used, then it can be prepared for disconnection by exporting the ZFS pool.

# zpool export -f zfoo

Detach GELI provider.

The external USB SSD can now be physically disconnected from the USB port and stored in a safe place.

# geli detach da0

Attach GELI provider.

When the USB SSD is to be used again, it is connected via USB and the GELI provider is attached by supplying the encryption key component and the password component. The provider can also be attached to another computer, if needed.

# geli attach -k foobar.key da0
Enter passphrase:

Import ZFS pool.

When the GELI provider has been attached, the ZFS pool can then be imported.

# zpool import zfoo

The external USB SSD is now mounted and is ready to be used.

Change passphrase and key file for GELI user key.

If you want to change the passphrase or the key file for the current GELI user key, you can do so with the GELI utility. The GELI framework support up to 2 different user keys. Each user key can have an optional passphrase, an optional key file or both. The user keys, and how they are set and deleted, is described in the setkey and delkey sections in the manual for GELI.

In the following example, a backup of the metadata is made, before a new passphrase and a new keyfile is set for the user key in slot 0 in the currently attached GELI provider. The passphrase is read from a text file. The key file is read from a new key file.

# geli backup da0 foobar.eli
# geli attach -k foobar.key da0
# nano foobar.txt
# dd if=/dev/random of=newfoobar.key bs=256 count=1
# geli setkey -J foobar.txt -K foobar.key -n 0 da0
# geli detach da0

The old passphrase and the old key file can no longer be used to attach and decrypt the file system.

# geli attach -k foobar.key da0
Enter passphrase:
geli: Wrong key for da0.
geli: There was an error with at least one provider.

How to decrypt a GELI encrypted SSD without encryption key and passphrase.

The two component setup significantly enhances security, because an attacker, that has access to the physical SSD, would need both components in order to decrypt and read data on the SSD. If the attacker has access to the physical SSD, but only in possession of one of these components, then the encryption remains effectively unbreakable.

AES-XTS with a 256-bit key is highly secure and used for military and government grade data encryption. Breaking this encryption by brute-forcing it would take an immense amount of computer power and time. More than what is possible with current technology.

In order to decrypt and access data, that is stored on GELI encrypted SSD storage, without the encryption key or passphrase, the attacker would need expert cryptographic skills, extraordinary computer resources and secret intelligence resources, which a three letter national state driven agency might have. Even then, the chance of success would be extremely low and hardly worth the effort.

As an open-source project, GELI is subject to public scrutiny of programmers and cryptographic experts, which ensure, that there are no intentional backdoors nor undiscovered weaknesses. The GELI project does not have its own official website. It is a part of the FreeBSD operating system and is documented in the storage chapter in the FreeBSD Handbook.

References.

Dynamic DNS (DynDNS, DDNS) with BIND

What is Dynamic DNS?

Dynamic DNS, also referred to has DynDNS or just DDNS, is a method, that can update ressource records (RR) in the zone of a DNS. An example of this is updating the IP address of a hostname. DNS updates must be authenticated by a transaction signature (TSIG). The update is performed using a DNS update utility.

Where is DDNS used?

DDNS is a requirement, where a client needs to provide a service from a server or host, that does not have a static IP address from the ISP. DDNS is also a requirement, where a client has security devices, such as DVRs and IP security surveillance cameras, that can not be reached via a static IP address from the ISP.

Confirm connection to IP address.

Confirm, that the service can be reached via the currently assigned IP address from Internet. If the service is behind a router, the dashboard of the router will show the currently assigned IP address. If you are using a VPN service, you can not use the IP address from the VPN exit node. If necessary, you will also need to allow and map access from Internet via the router to the service on your LAN.

% ping 13.37.13.37
% ssh -p 1337 -l foobar 13.37.13.37

If the service is behind a 5G router, that is connected to a modern 5G network, that use carrier-grade NAT, also known as CG-NAT or just CGN, then you will not be able to reach the service via the assigned IP address from Internet. The reason is, that the assigned IP address is actually shared between other routers. In that case, DDNS is no longer a solution. You might want to use a VPN instead. This way, the client and server can connect to a VPN server on a VPS with a static IP address.

To be continued…

More about DDNS.

How to create exFAT on USB drive with FreeBSD

Why use exFAT for USB drives and removable drives?

The exFAT, short for Extended File Allocation Table, file system supports very large volume sizes, which is one of the reasons, that it is used for larger USB drives and SD cards. exFAT does not have the 4 GB file size limit, that the FAT32 has. exFAT is compatible with different operating systems and physical devices.

Create exFAT on USB drive or removable drive.

If the the drive is already mounted, then unmount it, before creating the exFAT file system.

# umount /dev/da0

Create the exFAT file system on the removable USB drive. The exFAT file system willl not have a partition scheme. This ensures compatibility.

# mkexfatfs /dev/da0
mkexfatfs 1.4.0
Creating... done.
Flushing... done.
File system created successfully.

Confirm, that it mounts.

# mount.exfat /dev/da0 /mnt
FUSE exfat 1.4.0 (libfuse2)

More about exFAT.

How to install privacy VPN on FreeBSD

This is the procedure for installing, configuring and using a privacy oriented VPN server, such as Mullvad or Proton, with OpenVPN on FreeBSD. Tested with OpenVPN 2.6 .10 on FreeBSD 13.2 on 2024-04-26.

Install OpenVPN client on FreeBSD.

Install OpenVPN. The package comes with an OpenVPN client.

# pkg install openvpn

Create a directory for VPN configuration files. Ensure, that login credentials can only be read by the OpenVPN client.

# find / -type d -name '*openvpn*'
# mkdir /usr/local/etc/openvpn
# chown openvpn:openvpn /usr/local/etc/openvpn

Install VPN configuration file for OpenVPN client on FreeBSD.

Get the VPN configuration file from the website of the VPN service. The configuration file should support FreeBSD or GNU/Linux operating systems. The protocol should be UDP. This ensures, that TCP problems, that can arise from encapsulating TCP packets in TCP packets, is avoided. Copy the VPN configuration file to the OpenVPN directory from above.

# chown openvpn:openvpn /usr/local/etc/openvpn/foobar.ovpn

Configure OpenVPN to start without asking for username and password.

If you want to be able to use VPN without OpenVPN client asking for username and password, then configure it to read the login credentials from a text file.

# nano /usr/local/etc/openvpn/foobar.ovpn
auth-user-pass /usr/local/etc/openvpn/foobar.txt

Then store the username and password in the text file. The username on the first line and the password on the next line. Note, that some VPN services provides optional features the VPN service. Such features can be enabled or disabled by modifying the username.

# touch /usr/local/etc/openvpn/foobar.txt
# chown openvpn:openvpn /usr/local/etc/openvpn/foobar.txt
# nano /usr/local/etc/openvpn/foobar.txt
QfHrW8QGf1OYjubt
5r8JzcOBIPNbq6pqhxA0L-FLTVrl4pIl3a0G8qUqyB-DzwFLLfuNlf6j

Configure DNS resolver up scripts for OpenVPN client on FreeBSD.

Ensure, that up scripts, that takes care of DNS resolver configuration, exist. This is not only important for operation, but also for avoiding DNS leak by using an DNS, that is not related to the VPN. The OpenVPN client comes with up and down scripts for this.

# nano /usr/local/etc/openvpn/foobar.ovpn
up /usr/local/libexec/openvpn-client.up
plugin openvpn-plugin-down-root.so /usr/local/libexec/openvpn-client.down

How to start and stop VPN with OpenVPN on FreeBSD.

Start the VPN by using the OpenVPN client with the VPN configuration file as the argument. Stop the VPN by pressing Ctrl+C.

# openvpn-client /usr/local/etc/openvpn/foobar.ovpn

How to start VPN automatically at boot time on FreeBSD.

Add it to the system configuration.

# nano /etc/rc.conf
openvpn_enable="YES"
openvpn_configfile="/usr/local/etc/openvpn/foobar.ovpn"
openvpn_dir="/usr/local/etc/openvpn"

The VPN can now be started and stopped with the system service utility.

# service openvpn start
# service openvpn stop

If a firewall is used, such as PF, then it might be necessary to create an up script, that can reload the firewall script during the startup process.

# nano /usr/local/etc/openvpn/pfreload.sh
#!/bin/sh
/usr/sbin/service pf reload
# chmod 0700 /usr/local/etc/openvpn/pfreload.sh

Add it to the system configuration.

# nano /etc/rc.conf
openvpn_flags='--script-security 2 --up "/usr/local/etc/openvpn/pfreload.sh"

Check IP address for VPN.

Go to What is My IP Address? and confirm, that the IP address is related to the VPN server.

Check DNS resolver for DNS leak.

Confirm, that the DNS resolver has been updated, so DNS leak is avoided. The DNS resolver should have the new VPN DNS as the first DNS and then your default DNS as the last DNS. This is important, because the system usually needs the regular DNS at boot time, before the VPN is loaded, to set time and other system related Internet queries.

# cat /etc/resolv.conf
search micski.dk
nameserver 10.10.0.1
nameserver 192.168.0.1

More about VPN on FreeBSD.

OpenVPN and PF at startup on FreeBSD Forums. OpenVPN on FreshPorts. Official website for OpenVPN.

Creating a FAT32 file system on USB flash drive with FreeBSD

This is the procedure for creating an MBR boot sector and a FAT32 file system on a USB flash drive and other removable media, so it can used for sharing files with Windows, TVs or other devices. This procedure is also known as formatting or partitioning.

Attach the external storage and identify the device. Optionally check for existing partitioning schemes and file systems on the device. Destroy any existing partitioning scheme even if it is not empty. Create a new partitioning scheme with an MBR boot sector. Add a new partition of the FAT32 type. Optionally confirm the new boot sector and partition. Construct a new MS-DOS FAT32 file system with optional label. The label, that can use up to 11 characters, is used by Windows and some devices to present the file system to the user. Consider putting a physical label on the flash drive as well. The USB flash drive is now ready to be mounted, used and unmounted again.

# dmesg
# gpart show
# gpart destroy -F /dev/da0
# gpart create -s mbr /dev/da0
# gpart add -t fat32 /dev/da0
# gpart show
# newfs_msdos -L FOOBAR -F 32 /dev/da0s1
# mkdir /mnt/foobar
# mount -t msdos /dev/da0s1 /mnt/foobar
# cp /home/foobar/foo.* /mnt/foobar/
# df -H /mnt/foobar
# umount /mnt/foobar

More about creating file systems.

GPART and NEWFS_MSDOS on FreeBSD Manual Pages. How to mount FAT32 formatted SD memory card on FreeBSD and How to mount exFAT formatted SD memory card on FreeBSD by myself.

X and GNOME for FreeBSD

Xrandr.

If you just attached a monitor to your computer, such an external monitor or TV via HDMI, you can activate it in GNOME with Xrandr. Just run the utility. If you want to configure it in GNOME, then go to GNOME settings and Display.

% xrandr
Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 16384 x 16384
eDP-1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 276mm x 155mm
   1920x1080     60.05*+  60.01    59.97    59.96    59.93  
DP-1 disconnected (normal left inverted right x axis y axis)
HDMI-1 disconnected (normal left inverted right x axis y axis)
DP-2 disconnected (normal left inverted right x axis y axis)
HDMI-2 connected (normal left inverted right x axis y axis)
   3840x2160     30.00 +  25.00    24.00    29.97    23.98  

GNOME Tweaks.

Go to Appearance and change Applications from Adwaita to Adwaita-dark. This will make non-GTK applications, such as third party applications, dark mode as well as the GNOME applications.

% gnome-tweaks