1

I just installed Alpine linux, and it all went as smoothly as i'd hoped, except for the wireless networking (and XFCE's Power button and reboot buttons being greyed out, but that's irrelevant here).

I won't be the one using the computer, the only two things it needs to be able to do is connect to wireless networks and access the internet via a browser. But because the people using this computer are complete goofs with tech, I can't really tell them to do this (alpine linux wireless connection guide) every time they change networks; the mere sight of a terminal would freak them out. And so I need to get them a GUI.

I tried messing around looking for network manager GUIs for Alpine linux. What i really need is something like Wicd, but I only found connman and networkmanager in Alpine's testing repositories, however neither of them would launch properly, I have doubts I could get wicd to work on my own even if I manage to learn how to create APKBUILDs and compile it on time..

So I thought in the end before I give up maybe I can create something with a script. I mean all I need it to do is what it says in the wireless connection guide on the alpine linux wiki, as sudo.

Just running

iwlist wlan0 scanning

Grepping my way to the ESSIDs and listing them all neatly, maybe ordered by signal strength. Then after one is selected a password prompt will show asking for the passphrase. And after that...

iwconfig wlan0 essid MyNet #set SSID
wpa_passphrase PASSPHRASE > wpa.conf #set Passphrase
wpa_supplicant -Dwext -iwlan0 -c ./wpa.conf #Connect

and that should do it. I can figure out ways to check for connectivity and automate the prompt and so on myself, but I need to know to begin with if this can be done without just writing a complete GTK or Qt program.

I would like to do this in a script kind of way quick and easy with something like Zenity, can it be done? Could someone give me an example? Thanks.

(Btw Alpine ships with ASH, not BASH, it'd be best if I can do the scripting in ASH, but if not I don't mind using BASH or Python)

  • If you just need buttons and password prompts, would something like python with tkinter for the interface work? – rexroni Aug 29 '15 at 20:16
  • @rexroni Probably, it just needs to be an easy and quick fix, i don't have the time to learn a whole new graphical library, I have like 2 days to get this to work. If you can provide an example that would be great, if it's close enough and I can get it to work, I'll mark it as an answer. Right now I'm working around using zenity and ash scripting for it looks like it can work at a glance. But it doesn't seem like zenity is playing too well with my environment (it doesn't have any decorations) I'd love to try tkinter and python to see if I get better results. But I'll need an example to start. – Cestarian Aug 29 '15 at 21:25
  • I haven't written any tkinter code since 2011, and then I was only just learning. But I remember it was pretty easy. Here's the first link on a duckduckgo search for "tkinter tutorial": tutorialspoint.com/python/python_gui_programming.htm – rexroni Aug 30 '15 at 3:56
  • I managed to do it with a crude mix of awk, sudo and zenity, I'll post my workaround shortly – Cestarian Aug 30 '15 at 20:08
1

After messing around for hours I managed to cook something decent up using zenity and some sudoers changes. I'll give a step by step how I did it all, in case someone else is caught in the ugly situation of being on a linux distro that only has obsolete wireless networking software (like wireless-tools) without any easy way to get a known GUI like wicd...

Dependencies:

ash(or bash), sudo, zenity, awk, wget, ping, wpa_supplicant, wireless-tools (ip, iwlist, iwconfig, wpa_passphrase)

It also optionally depends on notify-send (those instances can easily be replaced with zenity --notification though)

First off I had to set the sudoers file to allow my/all users to run a few specific commands, this is the line (note that I am using alpine linux, you may have the same programs as I do but their executables may be located in a different place, find the correct path for each one first)

You'll see one weird command in there (wpa_restart) we will create that file later on.

in sudoers(visudo):

ALL ALL=(ALL) NOPASSWD: /usr/sbin/iwlist, /usr/sbin/iwconfig, /sbin/ip /sbin/wpa_restart

Before I go on, lets set wpa_supplicant to start at boot (Open-RC users; systemd users will need to do this the systemd way)

rc-update add wpa_supplicant boot

After doing this log in as root (or use su) and run the following:

echo > /etc/wpa_supplicant/wpa_supplicant.conf
chmod +777 /etc/wpa_supplicant/wpa_supplicant.conf
chmod -r /etc/wpa_supplicant/wpa_supplicant.conf
echo > /usr/sbin/wireless_gui
chmod +x /usr/sbin/wireless_gui
echo > /usr/sbin/wireless_check
chmod +x /usr/sbin/wireless_check
echo > /sbin/wpa_restart
chmod +x /sbin/wpa_restart

Next lets actually fill up those files with some scripts...

/sbin/wpa_restart (this only works for open-rc, systemd users will need something different, this file is used to restart wpa_supplicant for example if you are switching between connections, or if your connection fails and you need to reconnect and such):

#!/bin/ash
rc-service wpa_supplicant restart

/usr/sbin/wireless_check (checks for connectivity, and launches ssid selection gui if there is none):

#!/bin/ash 
wget -q -s http://google.com 
if [[ $? -eq 0 ]]; then 
    eth=$(ifconfig eth0 | grep inet addr)
    if [ $eth !=" " ];then
        SSID=$(iwconfig wlan0 | grep ESSID | cut -d: -f2 ) 
        notify-send "Connected to Wireless Network" "$SSID"
    else
        notify-send "Connected Via Ethernet" ""
    fi
else 
    /usr/sbin/wireless_gui 
fi

/usr/sbin/wireless_gui (the main deal):

#!/bin/ash 
sudo ip link set wlan0 up
ssid=$(sudo iwlist wlan0 scanning | awk -F: 'BEGIN{ printf "zenity --list --text \"Available Networks\" --list --column ESSID --column Security --column Signal "; }/Quality/{ split($0,x,"="); Quality = int(x[2]*100/70+.5); }/Encryption/{ Encryption = $2; }/ESSID/{ ESSID = $2; printf "%s \"%s\" \"%s%%\" \\\n", ESSID, Encryption, Quality}' |sh); 
if [ $ssid !=" " ]; then
    zenity --warning --text "Failed to select network!"
else
    $1="30"
    echo $1
    sudo ip link set wlan0 down 
    sudo iwconfig wlan0 essid $ssid 
    wpa_passphrase $ssid > /etc/wpa_supplicant/wpa_supplicant.conf $(zenity --password --title "Secured Network")
    sudo ip link set wlan0 up 
    sudo wpa_restart
    sleep 2
    success=$(ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3` > /dev/null && echo ok || echo error)
    if [ $success = "error" ]; then
        echo $success
        zenity --question --title "Wrong Password" --text "Retry?"
        while [[ $? -eq 0 ]]; do
            wpa_passphrase $ssid > /etc/wpa_supplicant/wpa_supplicant.conf $(zenity --password --title "Secured Network")
            sudo wpa_restart
            sleep 2
            success=$(ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3` > /dev/null && echo ok || echo error)
            if [ $success = "error" ]; then
                zenity --question --title "Wrong Password" --text "Retry?"
            else
                notify-send "Connected to Wireless Network" "$ssid"
                break
            fi
        done
    else
        notify-send "Connected to Wireless Network" "$ssid"
    fi
fi

Now that's what I call working with what you've got :)

Now get out of that root/su prompt, run wireless_gui once as a user and see if everything works, and you're done.

If it doesn't work the only thing that can be wrong is that you don't have ash (replace #!/bin/ash with #!/bin/bash to fix), you got one of the paths wrong in sudoers, you forgot one of the chmod commands, your wireless interface is not called wlan0 (use ifconfig or ip link to find out, and then rename all mentions of wlan0 to whatever it is your interface is named) or of course, you're missing a dependency.

The way this should be set up ideally is that wireless_check is run everytime you log in to a desktop environment. It checks for internet connectivity and then throws a notification if you're connected, launches wireless_gui if you're not. Wireless GUI will scan for and list all nearby ESSIDs, you pick one, then enter a password. If it fails to connect it will ask you if you want to retry typing the password until you either succeed or say no.

A really nice solution if you either don't want to install a network manager, or if you (like me) can't.

  • Allowing all users NOPASSWD root access to /usr/sbin/iwlist, /usr/sbin/iwconfig, /sbin/ip and /sbin/wpa_restart is a bad idea. it would be better to write simple shell script wrappers around them (that either take no args or sanity-check the args) and allow sudo access to the wrapper. Then call the wrapper from your main script with sudo. – cas Nov 16 '15 at 7:42
  • Hmm maybe, I did this for convenience, so you basically mean that I should just allow nopasswd access to the scripts themselves instead of iwlist/iwconfig and ip so that arguments can't be passed? Do I need to do something specific to prevent them from taking arguments? I'm not sure if I understand fully what you mean. – Cestarian Nov 16 '15 at 7:56
  • for example: giving a user sudo access to ip means that they can make any changes they want to your network interfaces, without restriction. giving them sudo access only to a wrapper script that you have written which does only a very limited subset of things with ip only allows them to change the things you've enabled in your wrapper script. same for ifconfig, iwconfig, etc. writing sudo wrapper scripts like this is security 101 - never give away more privs than is absolutely necessary to do the job at hand. – cas Nov 16 '15 at 8:48
  • as for passing args - the less user-supplied input that the sudo wrapper script has to process, the better. if you can get away with no args (because you know in advance what args to supply to ip or whatever) then that's great. if you have to take some args, take as few as possible, sanity-check them (e.g. if the script is meant to modify wlan interfaces, don't allow user to specify eth or ppp interfaces). and always quote your variables - e.g. use "$ip" or "$iface", not bare unquoted $ip or $iface. – cas Nov 16 '15 at 8:51
  • Thanks! I get it, why though quote the variables? – Cestarian Nov 16 '15 at 18:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.