How to set up a Bash Shell CGI HTTP server using BusyBox

Default featured post

Setting up a CGI server could be quite exciting, yet unsafe at the same time. This post explains how to set up a Bash Shell CGI HTTP server using BusyBox and generate some HTML pages using Bash script.

Disclaimer: Use this guide to have fun experimenting with CGI. Discover how HTTP requests are handled by a web server. It is highly advised against using this guide, CGI approach in overall, to create any real-world/production application.


CGI stands for Common Gateway Interface which is an old school way of running applications on web servers (web applications). Basically, it is an approach that allows web servers to execute standalone console applications to process user requests, usually HTTP. CGI allows developers to dynamically generate web pages by executing CGI scripts and reading users’ input submitted in HTML form via standard input.

Differences between CGI and a web container (e.g. Tomcat):

  • CGI creates a new process for each request at the OS level, whereas a proper container (such as Tomcat) creates a thread per request. Thus, a CGI application is vulnerable to D/DOS and server crash. However, usually, a D/DOS attack on a web app running in a container results in the container crash.
  • CGI is slow due to how data is processed and passed between processes.
  • CGI is not scalable. It will be ended with a giant monolithic application.
  • CGI languages (C, Perl, Bash) are poorly suited for creating web applications.
  • Error handling is hell in CGI.
  • Session management is tough in CGI because it’s too low level.

Setting up a CGI server with BusyBox

Installing BusyBox

The first step is to have BusyBox installed with its httpd command enabled. Depends on your machine and distro, this step may vary. Generally, most Linux distros have BusyBox installed by default. In Debian based distros you can install BusyBox using this command:

$ sudo apt install busybox

Creating CGI directories

The next step is to create a cgi-bin directory that hosts Bash scripts. For example,

$ mkdir -p /tmp/cgi-server/cgi-bin/

Creating a simple Bash script

Go to cgi-bin folder and create a Bash script named with the following contents:

echo "Content-type: text/html" # Tells the browser what kind of content to expect
echo "" # An empty line. Mandatory, if it is missed the page content will not load
echo "<p><em>Hello World!</em></p>" # Prints `Hello World!` in italic

Save the file and gave the permission for it to run:

$ chmod +x

Start Busybox HTTP server

The last step is to run httpd (HTTP Demon) via BusyBox like this:

$ sudo busybox httpd -p [port number] -f -v -h [path to the parent directory of `cgi-bin` directory]
  • -f is used to run httpd in foreground.
  • -v runs httpd in verbose mode. So any logs can be viewable.

Example command:

$ sudo busybox httpd -p 8080 -f -v -h /tmp/cgi-server/ # Keep in mind to point to `cgi-bin` parent directory

Test the application

Open your browser type localhost:8080/cgi-bin/ in address bar and hit enter. You should be able to see Hello World! message.

More complex example

You can execute any Bash command and get the result of it and show in HTML form. One example could be listing all the files of / directory and the current time. The CGI script will look like this:

echo "Content-type: text/html"
echo ""
echo "<p><strong>List of all files in </strong><code>/</code><strong> as of </strong><em>`date`</em></p>"
files=($(ls /))
for file in "${files[@]}"
echo "<code>$file</code><br>"

Save the code as Open browser and type localhost:8080/cgi-bin/ You should be able to see list of files/directories under / path of your machine.

There is no need to stop and start again the HTTP server when changing the file. Just modify, save and refresh the browser. The effect is immediate.

It is not recommended to run httpd with root privilege. A better approach is to create a specific user and give proper permissions to run the server.