Minimal TUI Wi-Fi Manager

From Run Your Own
Jump to navigation Jump to search

Good news! If you don't want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don't worry, Linux has all the CLI tools necessary to create a minimal on-demand TUI shell script thing to connect to, and manage these very Wi-Fi connections. The following info is for Debian, however the approach will be the same for other distros, including BSD operating systems that will differ mostly for some of the network commands. Why would you do this? I dunno, aesthetics, religious beliefs, limited resources, or just an opportunity to better understand what's running in the background.

How does it work?

The things that mater

  • /etc/network/interfaces — network interface configuration for ifup and ifdown
  • iw — show/manipulate wireless devices and their configuration
  • wpa_cli — WPA command line client
  • wpa_supplicant and wpa_supplicant.conf — Wi-Fi Protected Access client and IEEE 802.1X supplicant and its configuration file
  • fzf — command line fuzzy finder

Use case

The use case here is as follow:

  • don't connect to a Wi-Fi hotspot unless I explicitly ask the COMPUTAR to do so
  • if I need to connect to a Wi-Fi hotspot, the COMPUTAR should give me a list of the visible ones
  • a user-friendly™ interface with fuzzy search should help me tell the COMPUTAR which visible hotspot I want to connect to
  • once selected and if the Wi-Fi hotspot is already known, the COMPUTAR shall connect to it
  • however if the Wi-Fi hotspot is unknown, the COMPUTAR shall kindly ask me for the password, and if I agree to fulfill this request, the COMPUTAR shall save it, and proceed to connect to the hotspot
  • Oh no. I am now connected with more COMPUTARS

Note: if the Wi-Fi hotspot needs to be configured with specific settings (for instance for specific key management settings of for open networks), it is necessary to edit the wpa_supplicant.conf file manually. My rationale is that I need to do this so rarely, that quickly editing a file with a lot of obscure settings outweighs by far the need to make a more complicated shell script to handle such corner case. YMMV :)

Config and script

/etc/network/interfaces

Edit /etc/network/interfaces and adjust to your network name (here wlp2s0).

auto wlp2s0
iface wlp2s0 inet manual
  wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

wpa_supplicant.conf

If you start from scratch the only thing you need in this file is this:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev

If you already have some entries listed (in case you have been using a wifi network manager), make sure to disable each network with disabled=1. This is needed to prevent wpa_supplicant to :

# Settings for my nice network
network={
  ssid="La Compagnie Créole"
  psk="AU BAL AU BAL MASQUÉ OHÉ OHÉ"
  disabled=1
}

The shell script

#!/bin/sh
set -e

W_IF="wlp2s0"  # change with your right interface
WPA_CONF="/etc/wpa_supplicant/wpa_supplicant.conf"

# bogus call of sudo to force auth so as to not be bothered by fzf blocking
# the prompt later on.
# assumes that you're not being prompt for passwd at every single call :)
sudo echo -n

# with a little help from my friends
get_essid ()
{
  ESSID=$(sudo iw ${W_IF} scan | rg "\tSSID" | \
    sed -e 's/^.*SSID: //g' | sort | uniq | fzf )
}

known_essid ()
{
  ID=$(wpa_cli list_networks | rg -F "${ESSID}")
}

connect_essid ()
{
  echo "${ESSID} found, connecting..."
  echo
  wpa_cli enable_network ${ID}
  # uncomment following if using with wpa-conf
  #echo
  #sudo dhclient -v ${W_IF}
}

add_essid ()
{
  while true
  do
    echo "password plz"
    read ESSID_PASSWD
    while true
    do
      echo "is \"${ESSID_PASSWD}\" correct?"
      read ANSWER_PASSWD
      if [ "${ANSWER_PASSWD}" = "y" ]
      then
        sudo sh -c "cat >> /etc/wpa_supplicant/wpa_supplicant.conf" <<-EOF
	# ${ESSID}
	network={
	  ssid="${ESSID}"
	  psk="${ESSID_PASSWD}"
	  disabled=1
	}
	
	EOF
        break
      fi
    done
    break
  done
  echo "${ESSID} added, connecting..."
}

# Here we go
#cat ~/bin/fox.txt # aesthetics
get_essid
if known_essid
then
  connect_essid
  break
else
  while true
  do
    echo "dunno, add?"
    read ANSWER_ADD
    if [ "${ANSWER_ADD}" = "y" ]
    then
      add_essid
      wpa_cli reconfigure
      known_essid
      connect_essid
      break
    fi
  done
fi

tweaks

This setup makes use of the wpa-roam feature of wpa_action under Debian. This means that once connected to an hotspot, the underlying network system will under certain circumstances hop to another access point of the same name/type and, if needed, renegotiate a new IP. Why? Well as the word roam implies, this is handy if you are moving around a building with a bunch of access points all serving the same SSID. If this is not acceptable for whatever reasons, it's possible to prevent this behavior and be connected only to the hotspot/ap you have allowed in the first place. For this you need to edit /etc/network/interfaces like this:

auto wlp2s0
iface wlp2s0 inet manual
  wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

And because you will loose the automatic IP request negotiation, you need to un-comment in the script the two lines that call dhclient in connect_essid ().