Translated using DeepL

Machine-translated page for increased accessibility for English questioners.

What is a CGI script?

A CGI script is a program you create that allows you to generate dynamic WWW pages, i.e. pages that can look different each time they are opened. The content may depend on the current time, the contents of various files, the address of the computer from which the page is visited, etc.

How to create a CGI script

A CGI script is any (server-side) executable file (but usually a script - hence the name) that, when run, outputs the HTTP header of a page (not to be confused with the HTML header) and then its actual content to standard output. This can be classic HTML text, but can also be any other type of data.

The script should generate at least the header Content-Type: followed by a blank line that indicates the end of the header. An example of a simple CGI script written in the shell bash:

#!/bin/bash

echo "Content-Type: text/html"
echo
echo "<body>"
echo "my first example page \o/"
echo "<pre>"
date
echo "</pre>"
echo "</body>"

Here /bin/bash is the full path to the interpreter that should run the script on the server. It can be Bash, Perl, PHP or anything else. Beware, however, if you write your pages and scripts in editors or on systems that also store the CR character (Ctrl-M, ^M) at the end of lines - typically Windows programs. Then what you would be looking for is not the bash program in the /bin directory, but some kind of bash^M program, which of course doesn't exist.

Content-Type: is in this case text/html, which for a WWW server means that the CGI script generates an HTML page. If the script were generating, say, an image, Content-Type would be, say, image/gif.

The CGI script must be executable on Aise. For the WWW server to recognize that it is a CGI script, the script must have a .cgi extension.

User CGI scripts available under /~xlogin/

The CGI script must be executable by the owner, which you ensure with the command:

chmod u+x ~/public_html/script.cgi

If it is not a binary program, but actually a script, you also need to set the owner read permission.

Scripts are executed using the suexec mechanism, which allows the script to be executed under the identity of the owner. It also checks some security conditions. The basics are: the script must belong to the user that is listed in the URL ( https://www.fi.muni.cz/~xlogin/) and to the group that this user has as primary (can be found with the command id). Neither the script nor the parent directory must be write-enabled for the group and others. Suexec logs its activity to the file /var/log/httpd-user/suexec. In case of unmet security conditions, you can find the specific cause of the failure here.

CGI scripts stored outside the /~xlogin/ tree

These CGI scripts must be executable (permissions x) by the apachefi user; if it is not a binary program but a script, it must also be set to read permission ( r) by the apachefi user. This can be achieved with the command setfacl -m u:apachefi:r-x script.cgi. Runnable CGI scripts run under the identity of the user apachefi, and the behavior of the script must therefore be adapted to this. Typically, for example, this user can only write to the /tmp directory.

Special variables in CGI scripts, working with parameters in URLs

The WWW server sets several new variables that you can work with in a CGI script. You can find out which ones they are by following the example given in the section on debugging CGI scripts. Specifically, if you pass parameters to the CGI script (using the GET method), they will be available in the QUERY_STRING variable. In a shell CGI script, the processing of parameters might look like this:

#!/bin/bash
. /packages/run.64/bashlib-0.4/bin

echo Content-type: text/plain
echo

HOST=$(param host)

/usr/bin/host $HOST

This program will store the value of the parameter host in the variable HOST. So if you call the program using the URL https://www.fi.muni.cz/~xlogin/this_script.cgi?host=aisa, its output will be the output of host aisa. (See bashlib for more on bashlib.)

If you pass parameters using the POST method, the data is passed to the standard CGI script input.

CGI scripts and security

It is important to note that when a CGI script is invoked in the /~xlogin/ subtree, it runs under your identity. Therefore, if you make a security mistake in the script, your data on the server may be lost/altered or your identity may be otherwise compromised. Therefore, always check your script thoroughly before publishing it, and expect that someone may try to check the robustness and resilience of your script on their own. This is especially true for parameter handling.

Also keep in mind that the examples given on this page are illustrative (albeit functional) and may not be written securely. Before you start writing CGI scripts, it is recommended that you read up on the subject on the web.

Debugging CGI scripts

We recommend that you first try running the CGI script from the command line directly on Aise. Here you can catch e.g. interpreter error messages. It is very likely that after running under the user apachefi the script will not have some environment variables set (typically PATH, LD_LIBRARY_PATH, ...). For example, the following code will tell you the current state of the variables when the CGI script is running:
#!/bin/bash

echo "Content-type: text/plain"
echo
set

Debugging Perl scripts:

  • Use use CGI, which allows you to debug scripts on the command line, including parameters.
  • Use use CGI::Carp qw(fatalsToBrowser), which will display error messages to the browser.

Debugging shell scripts:

  • Just after the initial #!/path/to/interpreter (e.g. #!/bin/bash), add the line exec 2>/home/xlogin/public_html/stderr.log, which redirects the error output to a file.
  • If you are using modules, you need to initialize them first. See the page about modules for more details.

What to do if it still doesn't work:

  • Re-read this page.
  • Double-check that you have the correct access rights on the ~/public_html directory and nested (see the page on user HTML pages for details.
  • Double-check that the CGI script has the extension .cgi.
  • Recheck the access rights on the CGI script and its relevant environment.
  • Retry running the CGI script manually on Aise from the command line.
  • If the script works on the command line but not when accessed via the WWW, look in the WWW server logs for a possible cause. Where are the logs stored?
  • Consult with more experienced colleagues.
  • Consult with administrators.