since I upgraded my ipfire in 199 version, I have an error initialising hostapd
Jan 7 16:18:34 myfire hostapd: Configuration file: /etc/hostapd.conf
Jan 7 16:18:34 myfire hostapd: ctrl_interface_group=0
Jan 7 16:18:34 myfire hostapd: Line 22: invalid SSID ‘“”’
Jan 7 16:18:34 myfire hostapd: Line 27: invalid WPA passphrase length 1 (expected 8..63)
Jan 7 16:18:34 myfire hostapd: WPA-PSK enabled, but PSK or passphrase is not configured.
Jan 7 16:18:34 myfire hostapd: 3 errors found in configuration file ‘/etc/hostapd.conf’
Jan 7 16:18:34 myfire hostapd: Failed to set up interface with /etc/hostapd.conf
Jan 7 16:18:34 myfire hostapd: hostapd_init: free iface 0x181d08e0
Jan 7 16:18:34 myfire hostapd: Failed to initialize interface
Here is the fixed init script addressing both issues:
#!/bin/sh
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2007-2022 IPFire Team <info@ipfire.org> #
# #
###############################################################################
. /etc/sysconfig/rc
. ${rc_functions}
declare -A HT_CAPS=(
[0x0001]="[LDPC]"
[0x0002]="[HT40+][HT40-]"
[0x0010]="[GF]"
[0x0020]="[SHORT-GI-20]"
[0x0040]="[SHORT-GI-40]"
[0x0080]="[TX-STBC]"
[0x0400]="[DELAYED-BA]"
[0x0800]="[MAX-AMSDU-7935]"
[0x1000]="[DSSS_CCK-40]"
[0x4000]="[40-INTOLERANT]"
[0x8000]="[LSIG-TXOP-PROT]"
)
declare -A VHT_CAPS=(
[0x00000010]="[RXLDPC]"
[0x00000020]="[SHORT-GI-80]"
[0x00000040]="[SHORT-GI-160]"
[0x00000080]="[TX-STBC-2BY1]"
[0x00000800]="[SU-BEAMFORMER]"
[0x00001000]="[SU-BEAMFORMEE]"
[0x00080000]="[MU-BEAMFORMER]"
[0x00100000]="[MU-BEAMFORMEE]"
[0x00200000]="[VHT-TXOP-PS]"
[0x00400000]="[HTC-VHT]"
[0x10000000]="[RX-ANTENNA-PATTERN]"
[0x20000000]="[TX-ANTENNA-PATTERN]"
)
declare -A HE_MAC_CAPS=()
declare -A HE_PHY_CAPS=(
[0x08000000000]="he_su_beamformer=1"
[0x10000000000]="he_su_beamformee=1"
[0x20000000000]="he_mu_beamformer=1"
)
declare -A EHT_MAC_CAPS=()
declare -A EHT_PHY_CAPS=(
[0x0000000000000010]="eht_su_beamformer=1"
[0x0000000000000020]="eht_su_beamformee=1"
)
find_interface() {
local address="${1}"
local path
for path in /sys/class/net/*; do
if [ -s "${path}/address" ] && [ "$(<${path}/address)" = "${address}" ]; then
basename "${path}"
return 0
fi
done
return 1;
}
write_config() {
local interface="${1}"
local settings="/var/ipfire/wlanap/settings"
# FIX: Extract SSID and PWD directly and strip quotes to avoid $PWD collision
# and shell expansion issues with special characters.
local LOCAL_SSID=$(grep "^SSID=" "${settings}" | cut -d'=' -f2- | sed 's/^"//;s/"$//;s/^\x27//;s/\x27$//')
local LOCAL_PASS=$(grep "^PWD=" "${settings}" | cut -d'=' -f2- | sed 's/^"//;s/"$//;s/^\x27//;s/\x27$//')
# Fetch the PHY
local phy="$(</sys/class/net/${interface}/phy80211/name)"
local flag
local ht_flags=0
local vht_flags=0
local he_mac_flags=0
local he_phy_flags=0
local eht_mac_flags=0
local eht_phy_flags=0
# Set default BAND if none is set
if [ -z "${BAND}" ]; then
case "${HW_MODE}" in
gn) BAND="2g" ;;
*) BAND="5g" ;;
esac
fi
# Fetch PHY information
local line
while read -r line; do
case "${line}" in
"EHT MAC Capabilities"*) eht_mac_flags="${line:22:6}" ;;
"EHT PHY Capabilities"*) eht_phy_flags="${line:23:18}" ;;
"HE MAC Capabilities"*) he_mac_flags="${line:21:14}" ;;
"HE PHY Capabilities"*) he_phy_flags="${line:22:24}" ;;
"VHT Capabilities"*) vht_flags="${line:18:10}" ;;
"Capabilities: "*) ht_flags="${line:14}" ;;
"* 2412.0 MHz"*) [ "${BAND}" = "2g" ] && break ;;
"* 5180.0 MHz"*) [ "${BAND}" = "5g" ] && break ;;
esac
done <<<"$(iw phy "${phy}" info)"
local ht_caps=()
local vht_caps=()
local he_caps=()
local eht_caps=()
# HT Capabilities
for flag in ${!HT_CAPS[@]}; do
if (( ${ht_flags} & ${flag} )); then
ht_caps+=( "${HT_CAPS[${flag}]}" )
fi
done
# RX STBC
case "$(( (${ht_flags} >> 8) & 0x03 ))" in
1) ht_caps+=( "[RX-STBC1]" ) ;;
2) ht_caps+=( "[RX-STBC12]" ) ;;
3) ht_caps+=( "[RX-STBC123]" ) ;;
esac
# VHT Capabilities
for flag in ${!VHT_CAPS[@]}; do
if (( ${vht_flags} & ${flag} )); then
vht_caps+=( "${VHT_CAPS[${flag}]}" )
fi
done
# Supported channel width
case "$(( (${vht_flags} >> 2) & 0x03 ))" in
1) vht_caps+=( "[VHT160]" ) ;;
2) vht_caps+=( "[VHT160-80PLUS80]" ) ;;
esac
# VHT Max MPDU Length
case "$(( ${vht_flags} & 0x03 ))" in
1) vht_caps+=( "[MAX-MPDU-7991]" ) ;;
2) vht_caps+=( "[MAX-MPDU-11454]" ) ;;
esac
# RX Spatial Streams
case "$(( (${vht_flags} >> 8) & 0x03 ))" in
1) vht_caps+=( "[RX-STBC-1]" ) ;;
2) vht_caps+=( "[RX-STBC-12]" ) ;;
3) vht_caps+=( "[RX-STBC-123]" ) ;;
4) vht_caps+=( "[RX-STBC-1234]" ) ;;
esac
# Compressed Steering
case "$(( ((${vht_flags} >> 13) & 0x03) + 1 ))" in
2) vht_caps+=( "[BF-ANTENNA-2]" ) ;;
3) vht_caps+=( "[BF-ANTENNA-3]" ) ;;
4) vht_caps+=( "[BF-ANTENNA-4]" ) ;;
esac
# Sounding Dimension
case "$(( ((${vht_flags} >> 16) & 0x03) + 1 ))" in
2) vht_caps+=( "[SOUNDING-DIMENSION-2]" ) ;;
3) vht_caps+=( "[SOUNDING-DIMENSION-3]" ) ;;
4) vht_caps+=( "[SOUNDING-DIMENSION-4]" ) ;;
esac
local exponent="$(( (${vht_flags} >> 23) & 0x03 ))"
vht_caps+=( "[MAX-A-MPDU-LEN-EXP${exponent}]" )
# VHT Link Adaptation
case "$(( (${vht_flags} >> 26) & 0x03 ))" in
2) vht_caps+=( "[VHT-LINK-ADAPT2]" ) ;;
3) vht_caps+=( "[VHT-LINK-ADAPT3]" ) ;;
esac
# HE PHY Capabilities
for flag in ${!HE_PHY_CAPS[@]}; do
if (( ${he_phy_flags} & ${flag} )); then
he_caps+=( "${HE_PHY_CAPS[${flag}]}" )
fi
done
# EHT PHY Capabilities
for flag in ${!EHT_PHY_CAPS[@]}; do
if (( ${eht_phy_flags} & ${flag} )); then
eht_caps+=( "${EHT_PHY_CAPS[${flag}]}" )
fi
done
# Set the channel to zero if not set
[ -z "${CHANNEL}" ] && CHANNEL=0
# Translate the old HW_MODE to the newer MODE setting
if [ -z "${MODE}" ]; then
case "${HW_MODE}" in
ac) MODE="VHT20" ;;
an|gn) MODE="HT20" ;;
esac
fi
# Header
echo "# Automatically generated configuration - DO NOT EDIT"
echo "logger_syslog=-1"
echo "logger_syslog_level=4"
echo "driver=nl80211"
echo "country_code=${COUNTRY}"
echo "country3=0x49"
echo "ieee80211d=1"
echo "ieee80211h=1"
[ -n "${CHANNEL}" ] && echo "channel=${CHANNEL}"
echo "local_pwr_constraint=3"
echo "spectrum_mgmt_required=1"
echo "enable_background_radar=1"
echo "wmm_enabled=1"
# 802.11ac configuration
local enable_ac=0; local vht_oper_chwidth=0; local vht_oper_centr_freq_seg0_idx=""
case "${MODE}" in
VHT20|HE20|EHT20) enable_ac=1 ;;
VHT40|HE40|EHT40) enable_ac=1
if [ "${CHANNEL}" -gt 0 ]; then
case "$(( (${CHANNEL} / 4) % 2 ))" in
0) vht_oper_centr_freq_seg0_idx="$(( ${CHANNEL} - 2 ))" ;;
1) vht_oper_centr_freq_seg0_idx="$(( ${CHANNEL} + 2 ))" ;;
esac
fi ;;
VHT80|HE80|EHT80) enable_ac=1; vht_oper_chwidth=1
if [ "${CHANNEL}" -gt 0 ]; then
case "$(( (${CHANNEL} / 4) % 4 ))" in
0) vht_oper_centr_freq_seg0_idx="$(( ${CHANNEL} - 6 ))" ;;
1) vht_oper_centr_freq_seg0_idx="$(( ${CHANNEL} + 6 ))" ;;
2) vht_oper_centr_freq_seg0_idx="$(( ${CHANNEL} + 2 ))" ;;
3) vht_oper_centr_freq_seg0_idx="$(( ${CHANNEL} - 2 ))" ;;
esac
fi ;;
VHT160|HE160|EHT160|EHT320) enable_ac=1; vht_oper_chwidth=2
if [ "${CHANNEL}" -gt 0 ]; then
case "${CHANNEL}" in
36|40|44|48|52|56|60|64) vht_oper_centr_freq_seg0_idx=50 ;;
100|104|108|112|116|120|124|128) vht_oper_centr_freq_seg0_idx=114 ;;
149|153|157|161|165|169|173|177) vht_oper_centr_freq_seg0_idx=163 ;;
esac
fi ;;
esac
# 802.11ax/be configuration
local enable_ax=0; local he_oper_chwidth="${vht_oper_chwidth}"; local he_oper_centr_freq_seg0_idx="${vht_oper_centr_freq_seg0_idx}"
case "${MODE}" in HE*|EHT*) enable_ax=1 ;; esac
local enable_be=0; local eht_oper_chwidth="${he_oper_chwidth}"; local eht_oper_centr_freq_seg0_idx="${he_oper_centr_freq_seg0_idx}"
case "${MODE}" in EHT*) enable_be=1 ;; esac
# Set hardware mode
case "${BAND}" in
5g) echo "hw_mode=a" ;;
2g) echo "hw_mode=g" ;;
esac
# Enable 802.11be
if [ "${enable_be}" -eq 1 ]; then
echo "ieee80211be=1"
echo "eht_oper_chwidth=${eht_oper_chwidth}"
echo "eht_oper_centr_freq_seg0_idx=${eht_oper_centr_freq_seg0_idx}"
[ ${#eht_caps[@]} -gt 0 ] && printf "%s\n" "${eht_caps[@]}"
fi
# Enable 802.11ax
if [ "${enable_ax}" -eq 1 ]; then
echo "ieee80211ax=1"
echo "he_oper_chwidth=${he_oper_chwidth}"
echo "he_oper_centr_freq_seg0_idx=${he_oper_centr_freq_seg0_idx}"
[ ${#he_caps[@]} -gt 0 ] && printf "%s\n" "${he_caps[@]}"
fi
# Enable 802.11ac
if [ "${enable_ac}" -eq 1 ]; then
echo "ieee80211ac=1"
echo "vht_oper_chwidth=${vht_oper_chwidth}"
echo "vht_oper_centr_freq_seg0_idx=${vht_oper_centr_freq_seg0_idx}"
[ ${#vht_caps[@]} -gt 0 ] && echo "vht_capab=${vht_caps[@]}"
fi
# Enable 802.11n
echo "ieee80211n=1"
[ ${#ht_caps[@]} -gt 0 ] && echo "ht_capab=${ht_caps[@]}"
# Configure antennas
[ -z "${RX_ANTENNAS}" ] && RX_ANTENNAS="0xffffffff"
[ -z "${TX_ANTENNAS}" ] && TX_ANTENNAS="0xffffffff"
iw phy "${phy}" set antenna "${TX_ANTENNAS}" "${RX_ANTENNAS}" &>/dev/null
# General hostapd settings
echo "auth_algs=1"
echo "ctrl_interface=/var/run/hostapd"
echo "ctrl_interface_group=0"
echo "disassoc_low_ack=1"
# SSID Fix: Use Hex-Encoding (ssid2) to ensure special character compatibility
printf "ssid2=%s\n" "$(echo -n "${LOCAL_SSID}" | xxd -p)"
echo "utf8_ssid=1"
[ "${HIDESSID}" = "on" ] && echo "ignore_broadcast_ssid=2"
[ "${CLIENTISOLATION}" = "on" ] && echo "ap_isolate=1"
[ "${NOSCAN}" = "on" ] && echo "noscan=1" || echo "noscan=0"
# Management Frame Protection (802.11w)
case "${IEEE80211W}" in
on) echo "ieee80211w=2"; echo "beacon_prot=1"; echo "ocv=1" ;;
optional) echo "ieee80211w=1"; echo "beacon_prot=1"; echo "ocv=2" ;;
*) echo "ieee80211w=0" ;;
esac
# Encryption Fix: Use locally extracted password to bypass shell expansion bugs
case "${ENC}" in
wpa3)
echo "wpa=2"
echo "wpa_passphrase=${LOCAL_PASS}"
echo "wpa_key_mgmt=SAE"
echo "rsn_pairwise=CCMP" ;;
wpa2+3)
echo "wpa=2"
echo "wpa_passphrase=${LOCAL_PASS}"
echo "wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256 SAE"
echo "rsn_pairwise=CCMP" ;;
wpa2)
echo "wpa=2"
echo "wpa_passphrase=${LOCAL_PASS}"
echo "wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256"
echo "rsn_pairwise=CCMP" ;;
wpa1+2)
echo "wpa=3"
echo "wpa_passphrase=${LOCAL_PASS}"
echo "wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256"
echo "wpa_pairwise=TKIP"
echo "rsn_pairwise=CCMP" ;;
wpa1)
echo "wpa=1"
echo "wpa_passphrase=${LOCAL_PASS}"
echo "wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256"
echo "wpa_pairwise=TKIP" ;;
esac
# Steering and Optimization
case "${IEEE80211W}" in on|optional) echo "mbo=1"; echo "mbo_cell_data_conn_pref=1" ;; esac
echo "ssid_protection=1"
echo "extended_key_id=1"
echo "oce=7"
echo "interworking=1"
echo "access_network_type=0"
echo "internet=1"
echo "time_advertisement=2"
echo "multicast_to_unicast=1"
return 0
}
# Load general settings
# Note: SSID/PWD will be safely re-extracted in write_config
eval $(/usr/local/bin/readhash /var/ipfire/wlanap/settings)
case "${1}" in
start)
interface="$(find_interface "${INTERFACE}")"
if [ -z "${interface}" ]; then
boot_mesg "Could not find interface ${INTERFACE}"; echo_failure; exit 1
fi
if ! write_config "${interface}" > /etc/hostapd.conf; then
boot_mesg "Failed to generate configuration"; echo_failure; exit 1
fi
args=(/usr/bin/hostapd -s -B /etc/hostapd.conf -i "${interface}")
if [ -n "${DEBUG}" ] && [[ "${DEBUG}" =~ ^[0-9]+$ ]]; then
for (( i = 0; i < DEBUG; i++ )); do args+=( "-d" ); done
fi
boot_mesg "Starting hostapd... "; loadproc "${args[@]}" ;;
stop)
boot_mesg "Stopping hostapd..."; killproc /usr/bin/hostapd; evaluate_retval ;;
restart) ${0} stop; sleep 1; ${0} start ;;
status) statusproc /usr/bin/hostapd ;;
show-config)
interface="$(find_interface "${INTERFACE}")"
[ -z "${interface}" ] && exit 1
write_config "${interface}" ;;
*) echo "Usage: ${0} {start|stop|restart|status|show-config}"; exit 1 ;;
esac
There are two main problems in /etc/init.d/hostapd:
Variable Collision: The script uses $PWD, which is a reserved shell environment variable (Print Working Directory). When readhash tries to assign the password to PWD, it either fails or gets overwritten by the system.
Shell Expansion: Special characters like ! trigger Bash history expansion or misinterpretation during the eval $(readhash ...) process, leading to empty strings in the final hostapd.conf.
The Fix: Extract SSID and Passphrase directly from the settings file using grep and cut within the write_config function, bypassing the unreliable eval state. I also recommend using ssid2 with Hex encoding to make the SSID robust against any special characters.
Modified write_config section:
write_config() {
local interface="${1}"
local settings="/var/ipfire/wlanap/settings"
# Direct extraction to avoid $PWD collision and shell expansion issues
local LOCAL_SSID=$(grep "^SSID=" "${settings}" | cut -d'=' -f2- | sed 's/^"//;s/"$//;s/^\x27//;s/\x27$//')
local LOCAL_PASS=$(grep "^PWD=" "${settings}" | cut -d'=' -f2- | sed 's/^"//;s/"$//;s/^\x27//;s/\x27$//')
# ... (PHY detection logic) ...
# Fix for SSID (using hex encoding for safety)
printf "ssid2=%s\n" "$(echo -n "${LOCAL_SSID}" | xxd -p)"
echo "utf8_ssid=1"
# ... (other config) ...
# Fix for PSK assignment
case "${ENC}" in
wpa3|wpa2+3|wpa2|wpa1+2|wpa1)
echo "wpa_passphrase=${LOCAL_PASS}" ;;
esac
}
This approach ensures that the password and SSID are treated as literal strings, regardless of the characters they contain.
Can you dumb this down for those who don’t have the skill level to do this? Not sure what it means to extract a word from a file using grep and cut within a function…. Thanks in advance for your patience with those of us who are not as expert as others in such things. The problem I’m having is that I can initialize the wifi card and it shows up as “running”, but when I then check the hostapd service and go back to the card, it has stopped. Either hostapd or the card can be running but not both at the same time.
Also, I have made sure that there is no “!” in the passphrase, and also tried using no security and no passphrase at all. All in all I have been through about 15 changes in the configuration to address all of the possible issues I have been able to find but nothing has helped.
If you don’t know what those words mean then I would suggest not doing any editing on files directly in IPFire. You run the risk of creating a non-working system or worse a working system with a hole in it.
I would suggest that rather than trying to edit CU199 to do what you want, just update to the current released version (CU201).
The code requires that you use a minimum of 8 characters and a maximum of 63 characters.
Rather than just trying a range of different things and hoping you accidentally find what the problem is the best thing is to look in the logs and see what it says is the problem.
Look in the WUI menu - Logs - System Logs - Section: dropdown box entry labelled Wireless and then choose the appropriate month and day and press the Update button.
Then you can check the contents to see what the problem is but only do that if you still have a problem after you have updated to the current released version.
Thanks for your assistance! I did as you said and checked the specific log and found many messages relating to ACS or Automatic Channel Selection. It wasn’t liking it for some reason so I changed it to channel 6 and restarted it and it’s working now.