End-user Control of Wireless Networks Using Open-Source Software

The Request:

We recently had a client come to us with a very specific, albeit an unconventional request with regards to the type of wireless solution they envisioned. Due to concerns from some parents and faculty members, they wanted to limit the amount of RF signals the children were exposed to while at their school.

To meet this goal, they wanted the ability to enable and disable individual wireless access points so that they could provide wireless connectivity only when and where it was necessary for teaching specific classes, and then disable it all other times. They also wanted the process to be as simple as possible so that teachers would be able to easily manage the state of the wireless access points.

In an age when everyone expects 24/7/365 Internet access everywhere, they wanted to do the opposite.

The Options:

The first reccommendation we had was to install a managed wireless system such as Aruba, Aerohive, Ruckus, etc to provide full, proper wireless coverage when necessary but also allow teachers to access the administrative interface to enable or disable individual wireless radios.

However, if you have ever seen any of the managed wireless systems' interfaces, you will understand why giving teachers access to drill down to the access points, then find the correct one and then enable the radio would be a "bad thing"(TM). These interfaces are not complicated to your typical tech-savy user or systems administrator, but they can be quite a difficult thing for normal end-users to navigate.

Many of the managed wireless systems available will allow you to create additional administrative users, but each user typically has full rights to the entire wireless system, with no granular controls to limit what each user has access to. A simple mistake made by a non tech-savy user can cause problems for everyone and also cause costly service calls to restore wireless service.

We then discussed the option of installing a managed system capable of providing full coverage, but install a wall switch near each access point which would make/break the Power over Ethernet (PoE) connection to the access point. We really didn't like the idea of adding additional physical connections, the added wiring, and the possibility of just anyone (including children) being able to simply flick a switch to enable or disable the wireless access point(s). Also, the thought of troubleshooting such a system when the wall switches will inevitably end up behind a new cabinet, or bookshelf made this idea a non-starter.

When the client balked at the cost of a managed wireless system, we even discussed doing a similar thing as above using several unmanaged, access points instead.

The Solution:
Open-Source Software to the Rescue!

Based on some additional conversations and requirements, the solution we devised consisted of a combination of Voyage Linux on a PC Engines ALIX board, with Webmin's "Custom Commands" module to provide ON and OFF buttons in a very simple to use web gui.

Behind the scenes, the simple ON and OFF buttons displayed to the end user run a custom bash shell script which sends Simple Network Management Protocol (SNMP) commands to an SNMP-managed PoE switch to turn on or off the PoE power to the Ethernet ports that the access points are plugged in to.

Each of the pieces of software to be used: Voyage Linux, Webmin, Bash, and SNMP are all freely available as open-source software!

Hardware: PC Engines' ALIX board
PC Engines' line of small, reasonably priced, single-board computers are a perfect solution for firewalls or other small, and specific-use projects such as this one.

Operating System: Voyage Linux
The Voyage Linux website describes Voyage Linux as follows: "Voyage Linux is a Debian-derived Linux distribution that is best run on a x86 embedded platforms such as PC Engines ALIX/WRAP/APU, Soekris 45xx/48xx/65xx and Atom-based boards. It can also run on low-end x86 PC platforms. Typical installation requires 256MB disk space, although larger storage allows more packages to be installed. Voyage Linux is so small that it is best suitable for running a full-feature firewall, wireless access point, Asterisk/VoIP gateway, music player or network storage device."

The Web Interface: Webmin
The Webmin website describes Webmin as follows: "Webmin is a web-based interface for system administration for Unix. Using any modern web browser, you can setup user accounts, Apache, DNS, file sharing and much more. Webmin removes the need to manually edit Unix configuration files like /etc/passwd, and lets you manage a system from the console or remotely."

At Reverse Polarity, we often use Webmin on Linux servers when we need to give non-technical end-users access to specific server configurations or settings. The end-user works in a simple web interface, and we maintain the control, stability, and security of the systems involved.

In our Webmin-based solution, instead of everyone having full administrative rights to the wireless controller, teachers log into a simple interface and are presented with a list of ON and OFF buttons for the access points that they are allowed to control. Simple!

Slight change of plans...

The customer, finally realizing the benefits of a centrally managed wireless system over an unmanaged one, changed the requirements of this project one final time and decided to go with the controller-based managed solution which we originally recommended.

They still wanted teachers to be able to enable and disable access points, but they also wanted the benefits of a managed wireless solution, including the ability to expand it if/when they ever wanted to provide full coverage for their school. This final change of plans was not a problem because all the features of our Linux/Webmin/Bash/SNMP solution are still viable - only in a slightly different manner.

Now, with this final change to the requirements, instead of enabling/disabling PoE power to individual Ethernet ports on a PoE switch to turn unmanaged access points on or off, SNMP would be used to communicate with the wireless controller to turn the wireless radios in the access points on and off. Different, but still simple!

How it was done:

Wireless Controller: Ruckus ZoneDirector
For several reasons, including, cost, feature-set, familiarity with the system and SNMP manageability, we settled on the Ruckus ZoneDirector 1100 controller-based wireless system.

The Ruckus ZoneDirector controller is fully SNMP manageable, so we are able to query the status of the two radios in each of the access points, and turn them on and off as required using SNMP.

Operating System: Voyage Linux
Installing Voyage Linux onto a compact flash card, configuring its IP address and logging in is outside the scope of this how-to, but is a simple process of following the README link on the main download page here: Voyage Linux Download.

Software: SNMP
As mentioned above, we will be using SNMP (behind the scenes) to manage the state of the radios in the access points. From the Ruckus ZoneDirector SNMP Reference Guide, we determined the Management Information Bases (MIBs) that control the enable / disable state of the radios on the access points:

Radio 1:
Name: ruckusZDAPConfigRadioEnableWlanService24
Function: The AP enable wlan service flag on the 2.4 GHz radio.

Name: ruckusZDAPConfigRadioEnableWlanService5
Function: The AP enable wlan service flag on the 5 GHz radio.

By referencing these two MIBs from a Bash shell prompt, or in a Bash shell script, we will be able to read the status of the two radios in each access point with snmpget, and then turn them on or off using snmpset.

Enabling SNMP Management on Wireless Controller
Before any of this can work, we need to enable and configure SNMP access on the Ruckus ZoneDirector controller. This will allow us to talk to the ZoneDirector via SNMP.

Log into your ZoneDirector and click on the "Configure" tab:

Scroll down to the very bottom and click "Network Management" link:

Scroll down to the "SNMPv2 Agent" header. Check the "Enable SNMP Agent", and then fill in the System Contact, System Location, SNMP RO (read only) community string and the SNMP RW (read/write) community string and click the "apply" button at the far right of he page (not shown):

Now, the Ruckus ZoneDirector controller is ready to accept and respond to SNMP requests from the network.

Installing SNMP Support On Voyage Linux
We need to install the "snmp" Debian package into our Voyage Linux on ALIX system. This package will provide us with the snmpget and snmpset commands previously mentioned.
root@voyage:~# apt-get install snmp

Testing SNMP: 2.4GHz Radios
Now we use snmpget to query the status of the 2.4Ghz radios in access point 1 like so:

root@voyage:~# snmpget -v 2c -c abc123


  • -v 2c tells snmpget to use SNMP version 2c
  • -c abc123 is the the SNMP read/write community string we set in the Ruckus ZoneDirector controller the previous steps
  • is the IP address (or FQDN) of the ZoneDirector
  • The .1 at the very end of the MIB references access point #1 in the Ruckus system

The snmpget command returns the following output:

SNMPv2-SMI::enterprises.25053. = INTEGER: 1

The "= INTEGER: 1" at the end of this SNMP response means that the current state of the 2.4GHz radio in access point 1 is enabled. If the 2.4GHz radio in access point 1 were disabled, the output would be:

SNMPv2-SMI::enterprises.25053. = INTEGER: 2

Where the "= INTEGER: 2" indicates the radio is disabled.

Next, we can poll for the status of all of our 2.4GHz radios on all 19 of our access points with a short bash script like so:

root@voyage:~# let ap=1; while [ $ap -lt 20 ] ; do snmpget -v2c -c abc123 \$ap ; let  ap=$ap+1 ; done

This will output the following:

SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1

As you can see, all of the 2.4GHz radios on all 8 of our access points are currently enabled.

A more concise method is to use snmpwalk to walk the 2.4GHz radio SNMP branch like so:

root@voyage:~# snmpwalk -v2c -c 123abc

This will output the status only for existing radios and it should look the same as when we queried each radio one by one on the "for loop" above.

SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1
SNMPv2-SMI::enterprises.25053. = INTEGER: 1

Testing SNMP: 5GHz Radios
As noted above, the MIB for the 5Ghz radios ends with a .43 instead of the .34 for the 2.4GHz radios. We can repeat the status tests using the MIB for the 5GHz radio to make sure that querying the status of the 5GHz radios is also working as expected:

root@voyage:~# snmpget -v 2c -c abc123

SNMPv2-SMI::enterprises.25053. = INTEGER: 1

Which shows us that the 5GHz radio on access point 1 is also currently enabled.

Enabling and Disabling the Radios
Now that we know how to query the status of the two radios in all of our access points, we need to make sure we can also control them - which of course is the whole point of this exercise.

We turn off the 2.4GHz radio in access point #1 by using the snmpset command like so:

root@voyage:~# snmpset -v 2c -c abc123 i 2

The SNMP response to that command should look like this:

SNMPv2-SMI::enterprises.25053. = INTEGER: 2

As we learned from our snmpget request tests, the "= INTEGER: 2" at the end of that output indicates that the 2.4GHz radio in access point 1 is now disabled.

Now that we can control the state of our radios in our access points from the Linux command line using snmpget and snmpset, we need to provide this type of control to end-users via a friendly web interface. This is where Webmin comes in!

Software - Webmin
There is no Webmin package available in the default repositories that Voyage Linux comes pre-configured to use, so we will just manually download the Webmin Debian package directly from the Webmin website and install it with the Debian dpkg program.

Webmin also has several dependencies that are not part of the default install of Voyage Linux, so we need to install the following packages before installing Webmin:


As root we install these dependencies:

root@voyage:~# apt-get install libapt-pkg-perl python2.7 python-minimal libnet-ssleay-perl openssl libauthen-pam-perl/
libio-pty-perl apt-show-versions python

Once that is complete, and we have downloaded the Webmin package, we can install Webmin by running the following command as root:

root@voyage:~# dpkg -i webmin_1.680_all.deb

With Webmin installed, we need to start it. As root run:

root@voyage:~# /etc/init.d/webmin start

And check to see that it is listening on it's default port 10000:

root@voyage:~# netstat -tlpn | grep :10000

tcp        0      0 *               LISTEN      8350/perl

Webmin is now installed and running.

Logging Into Webmin

In a web browser, enter the IP address that the Voyage Linux device was set to and the Webmin port like so and you will see the login screen. By default, the only Webmin user created is "root" and the password is the Voyage Linux system's root user's password. The default root user's password on Voyage Linux is "voyage".

Once logged in, the main "System Information" page is displayed:

Configuring Webmin Custom Command Buttons

To start our configuration, we are first interested in the "Custom Commands" configuration page. This page is under the "Others" main menu dropdown option:

Select "Create a new custom command"

And fill out the form with the following information:

Description: This is the text that will appear on the button for this custom command.
HTML Description: This is text that will appear as normal text under the button. Since the buttons will have obvious names like "ON - Kindergarten APs" we will not need any HTML description.
Command: This is the actual command that will be run. It can be the path to a script, or bash shell commands may be entered directly into this box.

I decided that entering commands into the Command dialog box was a bit cumbersome, especially due to the fact that there is no way to keep any formatting to make it easy to read (indents, tabs etc). Once the command is saved, all formatting is lost.

Instead, I wrote a since bash shell script that would be called by each of our custom commands. The script accepts command line parameters so that we can pass it a Name of the access point(s) we wish to control (for display purposes), whether we want to turn the radios on the access point(s) ON or OFF, and which access point(s) to act on.

The script is named "wifi_control.sh" and is called in the following way:

/usr/local/sbin/wifi_control.sh [1 | 2] [Name] [AP list]


  • 1 = Enable, 2 = Disable
  • Name is a one word name of the access point(s) for the script to use
  • APs is the list of access points to act on - separated by spaces

Note: The wifi_control.sh script may be downloaded from the Download Script link. It needs to be edited and several site-specific variables configured. See Installing the Script section below

For the first button, we want to turn ON the two access points in the Kindergarten. We do so by entering the following command into the "Command" box:

/usr/local/sbin/wifi_control.sh 1 KindergartenAPs 7 8

Run as user: Select the radio button next to the text field and fill in the username "root"
Command Outputs HTML?: The end user will have a much better experience if we select "Yes" here. Our wifi_control.sh script will be written so that any text that it outputs will be formatted in HTML.
Hide command when executing?: Select "Yes" here so that only our the HTML from the wifi_control.sh script will be shown to the user.

All other options on the Create Custom Command page can be left as default. The only other option you may need to edit is the "Ordering on main page" option so that when you are finished the buttons will be organized in a sensible manner.

Click "Create."

Now, when the button labeled "ON – Kindergarten APs" is clicked, it will call the wifi_control.sh script, which in turn, will tell the Ruckus ZoneDirector to turn on both radios in access points 7 and 8. Don't click it yet, the wifi_control.sh script does not exist yet, and you will just get an error message.

To save time, Webmin has a "Clone" feature when editing a Custom Command. We currently have a command to turn on the radios in all of the Kindergarten APs, now we need one to turn them off. To do this just click "Edit command" under the "ON – Kindergarten APs" and then click "Clone" at the bottom of the "Edit Command" page.

You arrive at a new "Create Command" page populated exactly as the Custom Command page you just cloned. At this page, just change the word "ON" to "OFF" in the Description field and change the first "1" in the "Command" field to a "2", and then click "Create."

You now have two Custom Command buttons: One to turn on the radios in all of the Kindergarten access points (access points 7 and 8), and another to turn them off. To create the rest of the Custom Command buttons you just need to edit a command, any command, click clone, then modify the Description and the Command fields, save, and repeat the process until you have all the Custom Command buttons you need.

In the image below, we have a total of six buttons to control "All APs", "Kindergarten APs", and the "Library AP"

Users and Access Control

As previously mentioned, the only user in our Webmin system is "root." We do not want to give all users the root password, so we will need to create some groups and individual user accounts. Assigning our users to groups will allow us to show users only the buttons for the access points we would like them to have control of.

Creating and Configuring Groups
Under the "Webmin" main menu item is the "Webmin Users" page.

The first thing to do is create three groups to match the Custom Commands that have been previously created.

Click on "Create a new Webmin group" and fill in an appropriate group name and description.

NOTE: The name must be one word, otherwise Webmin will not accept it.

Click the "Available Webmin modules" dropdown to display a list of all available Webmin modules, scroll down until you see "Custom Commands" under the "Others" header and click the check box next to it. Click "Create" to create the group:

Repeat the process for the Kindergarten and Library groups. We now have three groups created, and they each have access to the "Custom Commands" menu item, but we still need to limit control to specific custom commands for each group of users.

To limit access to specific custom command buttons, we need to edit each group.

Click the "All_Access_Points" group and then click the "Available Webmin modules" dropdown. This time, you will notice that all of the listed modules are hyperlinks in your browser.

Scroll down to the "Other" header again, but this time click on the "Custom Commands" link:

This page is where you configure which custom commands this group has access to. We are currently working with the "All_Access_Points" group, so we select the "All Commands" radio button in the "Commands this user can run" option.

We do not want our users to edit the module configuration, nor do we want them to be able to create and edit commands, so we select the "No" radio buttons for those two options, click "Save" to save the "All_Access_Points" group's module access settings, and then click "Save" again to save all settings for the group.

Do the same for the other groups, but when you get to the page to select the "Commands this user can run", click the "Selected.." radio button, then press and hold the "CTRL" key and then left click each of the commands this group should have access to. The group here is "Library_Access_Points", so the two Library custom commands have been selected. Be sure to select the "No" radio buttons for the "Can edit module configuration" and "Can create and edit commands" options.

Click "Save" to save the Library group's module access settings, and then click "Save" again to save all settings for the group.

Repeat process for any other groups. Once all the groups are created and have access to the proper Custom Command buttons, the next step will be be to create our users and assign them to the appropriate groups.

Creating Users
Back at the main "Webmin Users" page, click the "Create a new Webmin user" link.

On the "Create Webmin User" page, enter a Username and then select the appropriate group from the dropdown. Set a password and the real name for this user. There are no other options that need to be set, so click "Create" and repeat the process for all your other users.

Now we have all of our groups and users created and configured:

Keeping It Simple For Your Users
To limit any confusion, and to limit the steps people have to take to get to the custom commands page, we can set Webmin to bring users immediately to the Custom Commands page.

Under the "Webmin" main menu option, select "Webmin Configuration" and then click "Index Page Options."

On this page, select the "Yes" radio button for the "Go direct to module if user only has one?" option.

Click "Logout" in the main menu,

Installing the Script

Setting Site-Specific Variables in the Script
The wifi_control.sh Bash shell script has several variables that need to be configured before it will work on your site. Most are self-explanatory:

The IP address, and the read/write SNMP community string for the ZoneDirector:


Administrative company name, company phone number, admin email address, who the email will be from, and the email subject:

admin="Reverse Polarity, LLC"
emailsubject="SNMP Error reported by SCHOOLNAME's Webmin device"

The text an end-user will see if there is an error. This can be set to anything you like. Remember that HTML can be used to format it for the end user:

usererrortxt="<h2>Ooops!</h2>An error was encountered while communicating with the Ruckus Controller.
<br><br><b>Please notify ${admin}<br>Phone: ${adminphone}<br>
Email: ${adminemail}<br>Note: An email has already been sent to the helpdesk.</b><hr>"

The text that will be sent in an email to the administrative email address:

adminerrortxt="SCHOOLNAME's Webmin device just reported an error communicating with their Ruckus Controller via SNMP."

The MIBS for the 2.4GHz, and 5GHz radios in the access points:


Copying and Setting Permissions on Script

On the Voyage Linux device, download the wifi_control.sh script like so:

root@voyage:~# wget http://www.revpol.com/files/wifi_control.sh

Then set it to be executable, and move it to the /usr/local/sbin directory like so:

root@voyage:~# chmod +x wifi_control.sh
root@voyage:~# mv wifi_control.sh /usr/local/sbin

Testing the Webmin Custom Command Buttons
Log back into Webmin as one of our normal (restricted) users.

NOTE: Login usernames are case sensitive.

Our users will only have access to the Custom Commands module page, and now they will be directed there immediately after logging in:

Notice that the user "Librarian" can only see the two custom command buttons for the Library Access Points. Also notice that there are no "Edit Command" links below the buttons.

Now, while logged in as the user "Librarian", click the "ON – Library AP" button:

If the wifi_control.sh script encounters a problem when running the snmpset commands to control the access points, the script will output an error message and email our helpdesk:

Displaying Status of All Radios:

Now that we can control the radios, lets set up another button to display the status of all of our access points and their radios.

Download the wifi_status.sh script the same way you downloaded the wifi_control.sh script, move it to the /usr/local/sbin directory and set its permissions. (see above)

Create a new button, give it a name like "Access Point Status" and set all the other options the same as the other buttons.

Save it and then on the main Custom Commands button, click it and you should see a similar output to this:

Now, go back to the "Webmin Users" page and edit your groups to make sur ethey have access to the new "Access Point Status" button.


There you have it! A highly configurable, web-based, end-user controlled wireless access system.

wifi_control.sh5.08 KB
wifi_status.sh6.06 KB

Post new comment

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <b> <i> <u> <strong> <cite> <code> <pre> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Enter the code without spaces and pay attention to upper/lower case.