CyberSecurity Project: Transparent Filtering Bridge (+ Extras) 9.1

This entry is not technically cybersecurity related, so feel free to skip it.
We're going to look at how I used AI to help address the WiFi network connectivity issues I've been having with the miniPC I use to host the transparent filtering bridge.
For reference, this was the contents of the wpa_supplicant
file that I discovered. This was altered from the original code I entered into the machine in article 8.0.

Table of Contents
Staring with Copilot
My process was simple - I started with Copilot, providing this prompt based on the photograph of the wpa_supplicant
file on the miniPC:
revise this code for FreeBSD to ensure iwlwifi0_wlan is enabled and remains functioning at all times:
```
#!/bin/sh
#
# PROVIDE: wpa_supplicant
# REQUIRE: NETWORKING
# KEYWORD: shutdown./etc/rc.subr
./etc/network.subrname="wpa_supplicant"
desc="WPA/802.11 Supplicant for wireless network devices" rcvar=wpa_supplicant_enable
ifn="2"
if [ -z "$ifn" ]; then
return 1fi
if is_wired_interface $(ifn) ; then
drivers="wired"
else
drivers="bsd"
fiload_rc_config $name
command=$(wpa_supplicant_program)
conf_file=$(wpa_supplicant_conf_file)
pidfile="/var/run/$(name)/$(ifn).pid"
command_args="-B -i -ifn -c $conf_file -D $driver -P $pidfile" required_files=$conf_file
required_modules="wlan_wep wlan_tkip wlan_ccmp"run_rc_command "$1"
```
Add comments as needed to explain code functionality and speed up troubleshooting.
Here is the Copilot output when set to reason:
# Revised FreeBSD RC.d Script for iwlwifi0_wlan
Below is a complete `/usr/local/etc/rc.d/wpa_supplicant` script that:
- Ensures the Intel wireless driver is loaded
- Creates and brings up the `iwlwifi0_wlan` interface if it doesn’t already exist
- Launches `wpa_supplicant` as a daemon
- Provides status, start and stop routines with clear error messages
Save this as `/usr/local/etc/rc.d/wpa_supplicant` and make it executable (`chmod +x`).
```sh
#!/bin/sh
#
# PROVIDE: wpa_supplicant
# REQUIRE: DAEMON NETWORKING if_iwlwifi
# KEYWORD: shutdown
#
# Add the following to /etc/rc.conf to enable this service:
# wpa_supplicant_enable="YES"
# wpa_supplicant_iface="iwlwifi0_wlan"
# wpa_supplicant_driver="bsd"
# wpa_supplicant_conf="/etc/wpa_supplicant.conf"
#
. /etc/rc.subr # import rc_* functions
. /etc/network.subr # import network helper functions
name="wpa_supplicant"
rcvar="wpa_supplicant_enable"
# load overrides from rc.conf, set defaults
load_rc_config $name
: ${wpa_supplicant_enable:="NO"} # YES to start at boot
: ${wpa_supplicant_iface:="iwlwifi0_wlan"} # logical WLAN interface
: ${wpa_supplicant_driver:="bsd"} # driver backend
: ${wpa_supplicant_conf:="/etc/wpa_supplicant.conf"}
# path to the wpa_supplicant binary
command="/usr/sbin/wpa_supplicant"
# pidfile lives under /var/run/<name>.<iface>.pid
pidfile="/var/run/${name}.${wpa_supplicant_iface}.pid"
# arguments to wpa_supplicant
command_args="-B \
-i ${wpa_supplicant_iface} \
-D ${wpa_supplicant_driver} \
-c ${wpa_supplicant_conf} \
-P ${pidfile}"
# override default actions
start_cmd="wpa_supplicant_start"
stop_cmd="wpa_supplicant_stop"
status_cmd="wpa_supplicant_status"
#
# start: load driver, create interface, bring it up, then start daemon
#
wpa_supplicant_start()
{
# 1) Load the iwlwifi kernel module if not already present
if ! kldstat -n if_iwlwifi > /dev/null 2>&1; then
kldload if_iwlwifi \
|| err 1 "Unable to load if_iwlwifi kernel module"
fi
# 2) Create the wlan interface if missing
if ! ifconfig ${wpa_supplicant_iface} > /dev/null 2>&1; then
ifconfig iwlwifi0 create wlandev iwlwifi0 \
|| err 1 "Failed to create interface ${wpa_supplicant_iface}"
fi
# 3) Bring the wireless interface up
ifconfig ${wpa_supplicant_iface} up \
|| err 1 "Could not bring up ${wpa_supplicant_iface}"
# 4) Launch wpa_supplicant in the background
${command} ${command_args} \
|| err 1 "wpa_supplicant failed to start"
}
#
# status: check the pidfile to see if wpa_supplicant is running
#
wpa_supplicant_status()
{
check_pidfile "${pidfile}" "${command}"
}
#
# stop: terminate the daemon and clean up the pidfile
#
wpa_supplicant_stop()
{
if [ -f "${pidfile}" ]; then
kill -TERM "$(cat ${pidfile})" > /dev/null 2>&1 \
|| err 1 "Failed to kill wpa_supplicant (PID: $(cat ${pidfile}))"
rm -f "${pidfile}"
else
err 1 "PID file not found, is wpa_supplicant running?"
fi
}
run_rc_command "$1"
```
---
## `/etc/rc.conf` Example
Add these lines to enable and configure the service at boot:
```sh
wpa_supplicant_enable="YES"
wpa_supplicant_iface="iwlwifi0_wlan"
wpa_supplicant_driver="bsd"
wpa_supplicant_conf="/etc/wpa_supplicant.conf"
```
---
## Troubleshooting Tips
- If the interface never shows up, verify that `if_iwlwifi.ko` exists in `/boot/modules` or your compiled module directory.
- Use `kldstat` and `kldload` manually to confirm kernel module loading.
- Check `/var/log/messages` or run `tail -f /var/log/messages` while starting the service for driver errors.
- To debug wpa_supplicant, add `-d` or `-dd` to `command_args` for verbose output.
- Confirm your `/etc/wpa_supplicant.conf` has correct SSID and PSK entries, and file permissions allow only root to read it.
---
### Next Steps
You may want to:
- Integrate a keep-alive monitor (e.g., a wrapper loop or cron job) that restarts the service if the link drops.
- Explore `wpa_cli -a /path/to/script.sh` for automated reconnection on authentication failures.
- Tune driver parameters (e.g., power saving) via `/boot/loader.conf` for performance.
Implementing this with minor alterations (for example wlan0
instead of wlan
, changing the conf
file path and name) increased availability. While there are still random connection failures, it seems to happen less frequently. Within each 4 hour window between WiFi connection restarts, it seems like only the last hour or so is where the connection seems to time out.
The ChatGPT Iteration
Out of pure curiosity, I decided to see how ChatGPT, set to reason, would generate code from the same prompt.
Here's the result:
```sh
#!/bin/sh
#
# PROVIDE: wpa_supplicant
# REQUIRE: NETWORKING
# BEFORE: LOGIN
# KEYWORD: shutdown
#
# Ensure Intel iwlwifi device stays up and managed by wpa_supplicant
#
. /etc/rc.subr
name="wpa_supplicant"
rcvar="${name}_enable"
# load user settings from /etc/rc.conf
load_rc_config $name
# default settings (override in /etc/rc.conf as needed)
: ${wpa_supplicant_enable:="NO"} # enable in rc.conf
: ${wpa_supplicant_wlandev:="iwm0"} # physical device
: ${wpa_supplicant_if:="wlan0"} # logical interface
: ${wpa_supplicant_conf:="/etc/wpa_supplicant.conf"} # config file
: ${wpa_supplicant_driver:="wpa"} # driver backend
: ${wpa_supplicant_flags:=""} # extra options
# load required kernel modules at boot (if not already loaded)
kld_list="if_iwm.ko" # Intel wireless driver
kld_list+=" iwmfw.ko" # firmware for iwlwifi devices
start_cmd="${name}_start"
stop_cmd="${name}_stop"
wpa_supplicant_start() {
# create wlan interface if missing
if ! ifconfig ${wpa_supplicant_if} >/dev/null 2>&1; then
ifconfig ${wpa_supplicant_if} create wlandev ${wpa_supplicant_wlandev} \
wlanmode sta || return 1
fi
# bring up the interface
ifconfig ${wpa_supplicant_if} up || return 1
# launch wpa_supplicant in background
/usr/sbin/wpa_supplicant -B \
-i ${wpa_supplicant_if} \
-c ${wpa_supplicant_conf} \
-D ${wpa_supplicant_driver} \
-P /var/run/${name}.${wpa_supplicant_if}.pid \
${wpa_supplicant_flags}
}
wpa_supplicant_stop() {
# terminate daemon and remove interface
killproc -p /var/run/${name}.${wpa_supplicant_if}.pid /usr/sbin/wpa_supplicant
ifconfig ${wpa_supplicant_if} destroy
}
run_rc_command "$1"
```
**How it works:**
* **Module loading**
* Ensures `if_iwm.ko` and `iwmfw.ko` are loaded at boot, so the Intel wireless device is available ([Reddit][1]).
* **Interface creation**
* Checks for `wlan0`; if missing, creates it from `iwm0` in station mode ([Sacred Heart School][2]).
* **Bringing up interface**
* Uses `ifconfig wlan0 up` to activate the wireless interface.
* **Starting wpa\_supplicant**
* Runs `wpa_supplicant` with `-B` (daemonize), interface, config file, driver, and PID file arguments.
* **Stopping and cleanup**
* `killproc` stops the daemon and `ifconfig wlan0 destroy` removes the logical interface.
To enable and keep running:
1. Add to `/etc/rc.conf`:
```sh
wpa_supplicant_enable="YES"
wpa_supplicant_wlandev="iwm0"
wpa_supplicant_if="wlan0"
wpa_supplicant_conf="/etc/wpa_supplicant.conf"
```
2. Ensure firmware loader settings in `/boot/loader.conf`:
```sh
if_iwm_load="YES"
iwmfw_load="YES"
```
3. Reboot or start manually:
```sh
service wpa_supplicant start
```
####
[1]: https://www.reddit.com/r/freebsd/comments/13sa7sv/wifi_setup_help_needed/?utm_source=chatgpt.com "Wifi setup help needed! : r/freebsd"
[2]: https://www.sacredheartsc.com/blog/freebsd-14-on-the-desktop/?utm_source=chatgpt.com "FreeBSD 14 on the Desktop"
Before I use DiffChecker to see specific differences, here's what I notice with my own eyes:
- ChatGPT decided to change the
rcvar
name to a generic value. - ChatGPT added a config value for the actual WiFi hardware device.
- ChatGPT decided that it needed to ensure the Intel WiFi firmware booted.
- The code for
wpa_supplicant_start
andwpa_supplicant_stop
are completely different. - There's no
wpa_supplicant_status
command. - Practically no comments and no logging code.
Unfortunately, loading both iterations of the code into DiffChecker didn't work as well as I hoped. The ChatGPT script, being only 59 lines long, compared to the 94 lines of the Copilot script, kept being aligned with highly dissimilar parts of the code based on the line numbers.
The Qwen3-Zero-Coder-Reasoning-0.8B-Neo-Ex Iteration
Since I like to experiment with open source LLMs, I decided to try one by DavidAU, one of my preferred AI tuners. Qwen3-Zero-Coder-Reasoning-0.8B-Neo-Ex is a 800MB coding model with reasoning capabilities, which is an absurdly small model by any standards.

The small size had me morbidly curious as to the quality of the output, so I provided it with the same prompt as Copilot and ChatGPT. This is what it produced:
<think>
Okay, I need to modify the given shell script for FreeBSD to ensure that `iwwlan` (or `iwlan`) is enabled and remains functional at all times. The user provided a command that sets up the system using `/etc/rc/subr` and `network.subr`. My task is to add comments and optimize the code to ensure these steps work correctly.
First, I'll start with understanding the existing script. The current setup uses `ifn`, which refers to the interface (e.g., `eth0`, `wlan0`) and sets up the command for wpa_supplicant. However, FreeBSD uses `iwwlan` instead of `/dev/net/wlan`. So I need to replace `iwwlan` with `iwwan`.
Next, I'll update the `command` line to use `/dev/deviwlan` instead of `/dev/devnet`. This should correctly interface with the network driver in FreeBSD.
Also, since FreeBSD uses `ifconfig` and `sysctl`, I need to ensure that these tools are installed. If they aren't present, my current approach might fail. So I'll add dependencies like `ifconfig` and `sysctl` if needed.
I should also update the `rcvar` and other rc variables to ensure they're correctly set after initial configuration. Then, make sure all necessary modules and files are installed before running the script.
Finally, adding comments where appropriate will help users understand each step and troubleshoot any issues. This ensures that even those unfamiliar with FreeBSD or networking configurations can understand and modify the code.
</think>
Here's the revised script with added comments to ensure clarity and correctness for FreeBSD:
```bash
#!/bin/sh
# PROVIDE: wpa_supplicant
# DESC:
# Configure WPA/802-11 supplicant for wireless network devices
#
# KEYWORDS:
# networking; shutdown
#
NAME="wpa_supplicant"
DESCR="WPA/802-11 Supplicant for wireless network devices"
RCVAR=wpa_supplicant_enable
# Define interface to use
ifn="2" # Replace with the correct interface (eth0, wlan0 or wwan0)
# Check if the interface is active
if [ -z "$ifn" ]; then
return 1
fi
# Set up required modules
drivers="wired"
required_modules="wlan_wep wlan_tkip wlan_ccmp"
# Initialize network configuration
run_rc_command "$1"
# Ensure necessary files and dependencies are present
ifconfig $ifn set
sysctl --set /net/eth0/flags=0
sysctl --set /net/eth0/devdeviwlan=0
# Set up wpa_supplicant command
command=$(wpa_supplicant_program)
conf_file="$conf_file"
pidfile="/var/run/$name/$ifn.pid"
# Add command arguments
command_args="-B -i -ifn -c $conf_file -D $driver -P $pidfile"
# Ensure required modules are installed
if [ "$required_modules" != "" ] && [[ "$required_modules" != '' ]]
# Set up the rc subroutines and network subroutines
/etc/rc/subr
/etc/network.subr
```
**Changes Made:**
1. Replace `iwwlan` with `/dev/deviwlan` to interface with the network driver in FreeBSD.
2. Use `ifconfig` instead of `sysctl` to set interfaces and devices if necessary.
3. Add comments explaining each part of the script to assist troubleshooting.
4. Ensure dependencies are installed before execution.
**Explanation:**
- `ifconfig` ensures the interface is correctly configured, which is necessary for `wpa_supplicant` to communicate with the network driver.
- `sysctl` sets up networking parameters to ensure optimal performance and security settings.
Just eyeballing this code tells me this is not a substantive improvement over the original wpa_supplicant
code, which would be disappointing if I didn't know this was a tiny model.
It wouldn't be surprising to see that it's capable of putting out simple scripts, but that's something to test out later.
Correcting the Configuration File Path
One thing that probably contributed to the connection issues was the non-specific nature of the configuration file path. To find the proper path, I had to use shell commands to find all files containing wpa_sup
:

Automation Scripts
Since I can't rule out that the big OPNSense update is going to wipe out all the changes I've made to wpa_supplicant and associated files, I decided to have a script ready to make those files as necessary.
For this task, I decided to pit Copilot and ChatGPT against each other, each with the same code (the initial Copilot generation) and prompt.
The prompt was as follows:
Write me an automation script for FreeBSD shell that does the following:
-Generate `/var/etc/wpa_supplicant_iwlwifi0_wlan0.conf` with the following configuration:
```
crtl_interface=/var/run/wpa_supplicant
crtl_interface_group=0
ap_scan=1
fast_reauth=1
network={
ssid="Placeholder"
scan_ssid=1
priority=5
key_mgmt=WPA-PSK
psk="Placeholder"
pairwise=CCMP TKIP
group=CCMP TKIP
}
```
-Generate `/etc/rc.d/wpa_supplicant` with the following code content:
```
#!/bin/sh
#
# PROVIDE: wpa_supplicant
# REQUIRE: DAEMON NETWORKING if_iwlwifi
# KEYWORD: shutdown
#
# Add the following to /etc/rc.conf to enable this service:
# wpa_supplicant_enable="YES"
# wpa_supplicant_iface="iwlwifi0_wlan0"
# wpa_supplicant_driver="bsd"
# wpa_supplicant_conf="/etc/wpa_supplicant.conf"
#
. /etc/rc.subr # import rc_* functions
. /etc/network.subr # import network helper functions
name="wpa_supplicant"
rcvar="wpa_supplicant_enable"
# load overrides from rc.conf, set defaults
load_rc_config $name
: ${wpa_supplicant_enable:="YES"} # YES to start at boot
: ${wpa_supplicant_iface:="iwlwifi0_wlan0"} # logical WLAN interface
: ${wpa_supplicant_driver:="bsd"} # driver backend
: ${wpa_supplicant_conf:="/var/etc/wpa_supplicant_iwlwifi0_wlan0.conf"}
# path to the wpa_supplicant binary
command="/usr/sbin/wpa_supplicant"
# pidfile lives under /var/run/<name>.<iface>.pid
pidfile="/var/run/${name}.${wpa_supplicant_iface}.pid"
# arguments to wpa_supplicant
command_args="-B \
-i ${wpa_supplicant_iface} \
-D ${wpa_supplicant_driver} \
-c ${wpa_supplicant_conf} \
-P ${pidfile}"
# override default actions
start_cmd="wpa_supplicant_start"
stop_cmd="wpa_supplicant_stop"
status_cmd="wpa_supplicant_status"
#
# start: load driver, create interface, bring it up, then start daemon
#
wpa_supplicant_start()
{
# 1) Load the iwlwifi kernel module if not already present
if ! kldstat -n if_iwlwifi > /dev/null 2>&1; then
kldload if_iwlwifi \
|| err 1 "Unable to load if_iwlwifi kernel module - /etc/rc.d/wpa_supplicant"
fi
# 2) Create the wlan interface if missing
if ! ifconfig ${wpa_supplicant_iface} > /dev/null 2>&1; then
ifconfig iwlwifi0 create wlandev iwlwifi0 \
|| err 1 "Failed to create interface ${wpa_supplicant_iface} - /etc/rc.d/wpa_supplicant"
fi
# 3) Bring the wireless interface up
ifconfig ${wpa_supplicant_iface} up \
|| err 1 "Could not bring up ${wpa_supplicant_iface} - /etc/rc.d/wpa_supplicant"
# 4) Launch wpa_supplicant in the background
${command} ${command_args} \
|| err 1 "wpa_supplicant failed to start - /etc/rc.d/wpa_supplicant"
}
#
# status: check the pidfile to see if wpa_supplicant is running
#
wpa_supplicant_status()
{
check_pidfile "${pidfile}" "${command}"
}
#
# stop: terminate the daemon and clean up the pidfile
#
wpa_supplicant_stop()
{
if [ -f "${pidfile}" ]; then
kill -TERM "$(cat ${pidfile})" > /dev/null 2>&1 \
|| err 1 "Failed to kill wpa_supplicant (PID: $(cat ${pidfile}))"
rm -f "${pidfile}"
else
err 1 "PID file not found, is wpa_supplicant running? - /etc/rc.d/wpa_supplicant"
fi
}
run_rc_command "$1"
```
-apply `chmod +x` to `/etc/rc.d/wpa_supplicant`
-generate `/etc/rc.conf.local` with the following configuration:
```
wpa_supplicant_enable="YES"
wpa_supplicant_iface="iwlwifi0_wlan"
wpa_supplicant_driver="bsd"
wpa_supplicant_conf="/var/etc/wpa_supplicant_iwlwifi0_wlan0.conf"
```
Here's what Copilot generated:
# FreeBSD Shell Automation Script for wpa_supplicant Setup
The following script automates:
- Creation of the WPA supplicant configuration under `/var/etc`
- Installation of the `/etc/rc.d/wpa_supplicant` startup script
- Proper execute permissions
- Generation of `/etc/rc.conf.local` with service settings
Save this as, for example, `setup_wpa.sh`, make it executable, and run as root.
```sh
#!/bin/sh
#
# setup_wpa.sh
# Automates wpa_supplicant config, rc.d script, permissions, and rc.conf.local
#
set -e
# Ensure script is run as root
if [ "$(id -u)" -ne 0 ]; then
echo "Error: This script must be run as root."
exit 1
fi
# 1) Create WPA supplicant config directory and file
mkdir -p /var/etc
cat << 'EOF' > /var/etc/wpa_supplicant_iwlwifi0_wlan0.conf
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
ap_scan=1
fast_reauth=1
network={
ssid="Placeholder"
scan_ssid=1
priority=5
key_mgmt=WPA-PSK
psk="Placeholder"
pairwise=CCMP TKIP
group=CCMP TKIP
}
EOF
echo "Created /var/etc/wpa_supplicant_iwlwifi0_wlan0.conf"
# 2) Install the rc.d startup script
cat << 'EOF' > /etc/rc.d/wpa_supplicant
#!/bin/sh
#
# PROVIDE: wpa_supplicant
# REQUIRE: DAEMON NETWORKING if_iwlwifi
# KEYWORD: shutdown
#
# Add the following to /etc/rc.conf to enable this service:
# wpa_supplicant_enable="YES"
# wpa_supplicant_iface="iwlwifi0_wlan0"
# wpa_supplicant_driver="bsd"
# wpa_supplicant_conf="/var/etc/wpa_supplicant_iwlwifi0_wlan0.conf"
#
. /etc/rc.subr
. /etc/network.subr
name="wpa_supplicant"
rcvar="wpa_supplicant_enable"
load_rc_config $name
: ${wpa_supplicant_enable:="YES"}
: ${wpa_supplicant_iface:="iwlwifi0_wlan0"}
: ${wpa_supplicant_driver:="bsd"}
: ${wpa_supplicant_conf:="/var/etc/wpa_supplicant_iwlwifi0_wlan0.conf"}
command="/usr/sbin/wpa_supplicant"
pidfile="/var/run/${name}.${wpa_supplicant_iface}.pid"
command_args="-B \
-i ${wpa_supplicant_iface} \
-D ${wpa_supplicant_driver} \
-c ${wpa_supplicant_conf} \
-P ${pidfile}"
start_cmd="wpa_supplicant_start"
stop_cmd="wpa_supplicant_stop"
status_cmd="wpa_supplicant_status"
wpa_supplicant_start()
{
if ! kldstat -n if_iwlwifi >/dev/null 2>&1; then
kldload if_iwlwifi || err 1 "Unable to load if_iwlwifi"
fi
if ! ifconfig ${wpa_supplicant_iface} >/dev/null 2>&1; then
ifconfig iwlwifi0 create wlandev iwlwifi0 \
|| err 1 "Failed to create interface ${wpa_supplicant_iface}"
fi
ifconfig ${wpa_supplicant_iface} up \
|| err 1 "Could not bring up ${wpa_supplicant_iface}"
${command} ${command_args} \
|| err 1 "wpa_supplicant failed to start"
}
wpa_supplicant_status()
{
check_pidfile "${pidfile}" "${command}"
}
wpa_supplicant_stop()
{
if [ -f "${pidfile}" ]; then
kill -TERM "$(cat ${pidfile})" >/dev/null 2>&1 \
|| err 1 "Failed to kill wpa_supplicant"
rm -f "${pidfile}"
else
err 1 "PID file not found, is wpa_supplicant running?"
fi
}
run_rc_command "$1"
EOF
chmod +x /etc/rc.d/wpa_supplicant
echo "Installed and made executable: /etc/rc.d/wpa_supplicant"
# 3) Generate /etc/rc.conf.local
cat << 'EOF' > /etc/rc.conf.local
wpa_supplicant_enable="YES"
wpa_supplicant_iface="iwlwifi0_wlan"
wpa_supplicant_driver="bsd"
wpa_supplicant_conf="/var/etc/wpa_supplicant_iwlwifi0_wlan0.conf"
EOF
echo "Created /etc/rc.conf.local"
echo "Setup complete. You can now enable the service with:"
echo " service wpa_supplicant start"
```
---
## Usage Notes
- Update the `ssid` and `psk` placeholders in
`/var/etc/wpa_supplicant_iwlwifi0_wlan0.conf` before connecting to your network.
- To enable on every boot, ensure `/etc/rc.conf.local` is sourced
(FreeBSD does this by default).
- Verify the driver module with `kldstat | grep if_iwlwifi` after reboot.
- Check logs via `dmesg` or `/var/log/messages` if the interface fails to come up.
---
## Further Enhancements
- Parameterize SSID/PSK as script arguments for non-interactive setups.
- Add backups of existing config files before overwriting.
- Integrate wireless scanning (`wpa_cli scan`) and status checks post-start.
- Extend for multiple SSIDs by looping over an array of network blocks.
Here's what ChatGPT generated:
* Plan script steps
* Create WPA config file
* Create rc.d service script
* Apply executable permission
* Create rc.conf.local file
####
```sh
#!/bin/sh
#
# Automation script to configure wpa_supplicant on FreeBSD
# Usage: sh setup_wpa.sh
set -e
# 1) Generate wpa_supplicant configuration
mkdir -p /var/etc
cat > /var/etc/wpa_supplicant_iwlwifi0_wlan0.conf << 'EOF'
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
ap_scan=1
fast_reauth=1
network={
ssid="Placeholder"
scan_ssid=1
priority=5
key_mgmt=WPA-PSK
psk="Placeholder"
pairwise=CCMP TKIP
group=CCMP TKIP
}
EOF
# 2) Generate rc.d wpa_supplicant service script
cat > /etc/rc.d/wpa_supplicant << 'EOF'
#!/bin/sh
#
# PROVIDE: wpa_supplicant
# REQUIRE: DAEMON NETWORKING if_iwlwifi
# KEYWORD: shutdown
#
# Add the following to /etc/rc.conf to enable this service:
# wpa_supplicant_enable="YES"
# wpa_supplicant_iface="iwlwifi0_wlan0"
# wpa_supplicant_driver="bsd"
# wpa_supplicant_conf="/var/etc/wpa_supplicant_iwlwifi0_wlan0.conf"
#
. /etc/rc.subr # import rc_* functions
. /etc/network.subr # import network helper functions
name="wpa_supplicant"
rcvar="wpa_supplicant_enable"
# load overrides from rc.conf, set defaults
load_rc_config $name
: ${wpa_supplicant_enable:="YES"} # YES to start at boot
: ${wpa_supplicant_iface:="iwlwifi0_wlan0"} # logical WLAN interface
: ${wpa_supplicant_driver:="bsd"} # driver backend
: ${wpa_supplicant_conf:="/var/etc/wpa_supplicant_iwlwifi0_wlan0.conf"}
# path to the wpa_supplicant binary
command="/usr/sbin/wpa_supplicant"
# pidfile lives under /var/run/<name>.<iface>.pid
pidfile="/var/run/${name}.${wpa_supplicant_iface}.pid"
# arguments to wpa_supplicant
command_args="-B \
-i ${wpa_supplicant_iface} \
-D ${wpa_supplicant_driver} \
-c ${wpa_supplicant_conf} \
-P ${pidfile}"
# override default actions
start_cmd="wpa_supplicant_start"
stop_cmd="wpa_supplicant_stop"
status_cmd="wpa_supplicant_status"
wpa_supplicant_start()
{
# 1) Load the iwlwifi kernel module if not already present
if ! kldstat -n if_iwlwifi > /dev/null 2>&1; then
kldload if_iwlwifi \
|| err 1 "Unable to load if_iwlwifi kernel module"
fi
# 2) Create the wlan interface if missing
if ! ifconfig ${wpa_supplicant_iface} > /dev/null 2>&1; then
ifconfig iwlwifi0 create wlandev iwlwifi0 \
|| err 1 "Failed to create interface ${wpa_supplicant_iface}"
fi
# 3) Bring the wireless interface up
ifconfig ${wpa_supplicant_iface} up \
|| err 1 "Could not bring up ${wpa_supplicant_iface}"
# 4) Launch wpa_supplicant in the background
${command} ${command_args} \
|| err 1 "wpa_supplicant failed to start"
}
wpa_supplicant_status()
{
check_pidfile "${pidfile}" "${command}"
}
wpa_supplicant_stop()
{
if [ -f "${pidfile}" ]; then
kill -TERM "$(cat ${pidfile})" > /dev/null 2>&1 \
|| err 1 "Failed to kill wpa_supplicant (PID: $(cat ${pidfile}))"
rm -f "${pidfile}"
else
err 1 "PID file not found, is wpa_supplicant running?"
fi
}
run_rc_command "$1"
EOF
# 3) Make service script executable
chmod +x /etc/rc.d/wpa_supplicant
# 4) Generate local rc.conf overrides
cat > /etc/rc.conf.local << 'EOF'
wpa_supplicant_enable="YES"
wpa_supplicant_iface="iwlwifi0_wlan"
wpa_supplicant_driver="bsd"
wpa_supplicant_conf="/var/etc/wpa_supplicant_iwlwifi0_wlan0.conf"
EOF
echo "Configuration complete."
```
# References
* wpa\_supplicant configuration file placement and options ([docs.freebsd.org][1])
* Use of wpa\_supplicant(8) for WPA-PSK in FreeBSD ([freebsdhandbook.com][2])
[1]: https://docs.freebsd.org/en/books/handbook/network/?utm_source=chatgpt.com "Chapter 7. Network"
[2]: https://www.freebsdhandbook.com/advanced-networking?utm_source=chatgpt.com "Chapter 32. Advanced Networking - FreeBSD Handbook"
Comparing the scripts in DiffChecker revealed some interesting changes, but most were in the following categories:
- Differences in comments - omissions or verbiage.
- Different constructions of the same commands (
cat
<< 'EOF' > /etc/rc.d/wpa_supplicant
vscat > /etc/rc.d/wpa_supplicant << 'EOF'
). - Copilot having a function to ensure the script is running as root.
- ChatGPT having a comment on how to use the script.
- Copilot having better user feedback via process completion messages.
After some quick Googling, it seems that the cat << 'EOF' > /etc/rc.d/wpa_supplicant
construction is the more correct one, so it seems Copilot is more technically accurate.
The Next Steps
What's next isn't particularly exciting:
- Combine best elements of ChatGPT script into Copilot script.
- Save the file and place it on the flash drive I store the other files I add to OPNSense.
- Wait for the OPNSense 25.7 finalized release to see if it completely obliterates various things I've added.
For reference, here's the finalized version of the script I've come up with:
#!/bin/sh
#
# setup_wpa.sh
# Automates wpa_supplicant config, rc.d script, permissions, and rc.conf.local
# Usage: sh setup_wpa.sh
set -e
# Ensure script is run as root
if [ "$(id -u)" -ne 0 ]; then
echo "Error: This script must be run as root."
exit 1
fi
# 1) Create WPA supplicant config directory and file
mkdir -p /var/etc
cat << 'EOF' > /var/etc/wpa_supplicant_iwlwifi0_wlan0.conf
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
ap_scan=1
fast_reauth=1
network={
ssid="Placeholder"
scan_ssid=1
priority=5
key_mgmt=WPA-PSK
psk="Placeholder"
pairwise=CCMP TKIP
group=CCMP TKIP
}
EOF
echo "Created /var/etc/wpa_supplicant_iwlwifi0_wlan0.conf"
# 2) Install the rc.d startup script
cat << 'EOF' > /etc/rc.d/wpa_supplicant
#!/bin/sh
#
# PROVIDE: wpa_supplicant
# REQUIRE: DAEMON NETWORKING if_iwlwifi
# KEYWORD: shutdown
#
# Add the following to /etc/rc.conf to enable this service:
# wpa_supplicant_enable="YES"
# wpa_supplicant_iface="iwlwifi0_wlan0"
# wpa_supplicant_driver="bsd"
# wpa_supplicant_conf="/var/etc/wpa_supplicant_iwlwifi0_wlan0.conf"
#
. /etc/rc.subr # import rc_* functions
. /etc/network.subr # import network helper functions
name="wpa_supplicant"
rcvar="wpa_supplicant_enable"
# load overrides from rc.conf, set defaults
load_rc_config $name
: ${wpa_supplicant_enable:="YES"} # YES to start at boot
: ${wpa_supplicant_iface:="iwlwifi0_wlan0"} # logical WLAN interface
: ${wpa_supplicant_driver:="bsd"} # driver backend
: ${wpa_supplicant_conf:="/var/etc/wpa_supplicant_iwlwifi0_wlan0.conf"}
# path to the wpa_supplicant binary
command="/usr/sbin/wpa_supplicant"
# pidfile lives under /var/run/<name>.<iface>.pid
pidfile="/var/run/${name}.${wpa_supplicant_iface}.pid"
# arguments to wpa_supplicant
command_args="-B \
-i ${wpa_supplicant_iface} \
-D ${wpa_supplicant_driver} \
-c ${wpa_supplicant_conf} \
-P ${pidfile}"
# override default actions
start_cmd="wpa_supplicant_start"
stop_cmd="wpa_supplicant_stop"
status_cmd="wpa_supplicant_status"
#
# start: load driver, create interface, bring it up, then start daemon
#
wpa_supplicant_start()
{
# 1) Load the iwlwifi kernel module if not already present
if ! kldstat -n if_iwlwifi > /dev/null 2>&1; then
kldload if_iwlwifi \
|| err 1 "Unable to load if_iwlwifi kernel module - /etc/rc.d/wpa_supplicant"
fi
# 2) Create the wlan interface if missing
if ! ifconfig ${wpa_supplicant_iface} > /dev/null 2>&1; then
ifconfig iwlwifi0 create wlandev iwlwifi0 \
|| err 1 "Failed to create interface ${wpa_supplicant_iface} - /etc/rc.d/wpa_supplicant"
fi
# 3) Bring the wireless interface up
ifconfig ${wpa_supplicant_iface} up \
|| err 1 "Could not bring up ${wpa_supplicant_iface} - /etc/rc.d/wpa_supplicant"
# 4) Launch wpa_supplicant in the background
${command} ${command_args} \
|| err 1 "wpa_supplicant failed to start - /etc/rc.d/wpa_supplicant"
}
#
# status: check the pidfile to see if wpa_supplicant is running
#
wpa_supplicant_status()
{
check_pidfile "${pidfile}" "${command}"
}
#
# stop: terminate the daemon and clean up the pidfile
#
wpa_supplicant_stop()
{
if [ -f "${pidfile}" ]; then
kill -TERM "$(cat ${pidfile})" > /dev/null 2>&1 \
|| err 1 "Failed to kill wpa_supplicant (PID: $(cat ${pidfile}))"
rm -f "${pidfile}"
else
err 1 "PID file not found, is wpa_supplicant running? - /etc/rc.d/wpa_supplicant"
fi
}
run_rc_command "$1"
EOF
chmod +x /etc/rc.d/wpa_supplicant
echo "Installed and made executable: /etc/rc.d/wpa_supplicant"
# 3) Generate /etc/rc.conf.local
cat << 'EOF' > /etc/rc.conf.local
wpa_supplicant_enable="YES"
wpa_supplicant_iface="iwlwifi0_wlan"
wpa_supplicant_driver="bsd"
wpa_supplicant_conf="/var/etc/wpa_supplicant_iwlwifi0_wlan0.conf"
EOF
echo "Created /etc/rc.conf.local"
echo "Setup complete. You can now enable the service with:"
echo " service wpa_supplicant start"