Writing Bash CGI Application for OpenWRT

When it comes to custom router firmware, OpenWRT is probably the best. If you build the firmware by yourself, you can skip all the preinstalled LuCi Web UI things and dial down the RAM usage to just 3-4 MB. One of the cool things about OpenWRT is its openness to let users modify everything. We can say it's a type of Linux distro running on your computer called Router. Heck, you can even install it on your Android TV Box. There are already prebuilt images for specific Android TV Boxes. You can just head over to this ophub/amlogic-s9xxx-openwrt , and install it. The installation procedure is really easy, it's the same as the installation of the Linux blog I wrote previously.

The usual build of OpenWRT already comes with a lightweight HTTP web server called uhttpd. It was designed for embedded systems with very low system resources, which explains its overall size and the operating system demand.

To access your web app that uses bash CGI, let's create a service on a different port. This will ease the process while exposing it to the internet if you are planning on tunneling it or proxying through other services.

To create a separate service for a port. You have to edit the uhttpd config file. To do that, ssh into your OpenWRT machine. And edit the config file located in /etc/config/uhttpd .

In the screenshot above, you can see that I have created a config with a name other . Inside it, I am exposing the webserver to port 8080, since port 80 is already being used by the LuCi.

config uhttpd 'other'
        list listen_http '0.0.0.0:8080'
        list listen_http '[::]:8080'
        option home        '/www/users/'
        option index_page  'test.cgi'
        option cgi_prefix '/'
        option rfc1918_filter '1'
        option max_requests '3'
        option max_connections '100'
        option cert '/etc/uhttpd.crt'
        option key '/etc/uhttpd.key'
        option script_timeout '60'
        option network_timeout '30'
        option http_keepalive '20'
        option realm 'users'
        option tcp_keepalive '1'

In the option home, put in the directory where you are planning to store your web applications files. In the option index_page, add the index page file name that you want to show while visiting the web server. For example, I have put a test.cgi as a filename, which I have it in the location.

Once you modify the config based on your needs, save it and restart the uhttpd service. You can do that by entering service uhttpd restart on the terminal.

Now you can go to the port 8080, and you should see the server working. Since we haven't added the files on the location, it might show an empty index page.

Now to create the web app using the bash CGI is not that hard. If you know bash scripts then you should be able to pick it up in no time. For those who are not familiar with it, I suggest that you read this awesome documentation.

You can see here that I have made a simple web app using bash CGI to control the internet access to the users I am sharing my home internet with. Since it's bash, you can execute shell commands directly from the web page.

Here's a small sneak peek into the code. I am using Bootstrap for the table and the buttons. The information like days remaining and expiry dates are generated dynamically on the web page by executing the shell commands.

For example, if you want to show the uptime of the system on your webpage you can do

#!/bin/bash

echo "<h3>$(uptime)"

You basically, echo out the language that your web program understands, i.e. HTML, CSS, and JS.

And that's how you start writing your own bash CGI application and deploy it into your OpenWRT. This is a basic way of controlling your OpenWRT from the web. Check out the official documentation on the uhttpd from the OpenWRT. There are many advanced things you can do with it like adding basic HTTP authentication, using php, and so on.