HowTo: Configure a Linux Apache Web Server on openSUSE 10.x and 11.x (including SSI and CGI)

Keywords: Apache, Suse, VirtualHost, CGI, Common Gateway Interface, SSI, Server Side Includes, Options, AddHandler, ScriptAlias, AllowOverride, XBitHack, .htaccess, LAMP

apache gif

Summary: This HowTo goes through installing and configuring an Apache web server in openSUSE. Steps/areas covered include:

  • • Software Installation
  • • Starting, stopping and testing Apache
  • • Main configuration files
  • • Server configuration
  • • Virtual Hosts & configuration
  • • Adding a domain
  • • Server Side Includes
  • • Common Gateway Interface
  • • Going Public

The tutorial proceeds by examles/recipes that are tested and work in Suse all versions of openSUSE. Feel free to use them after you change obvious things like IP addresses, domain names etc to suit your environment. Except for changing the IP address and the server name "lampserver", you could use the files almost verbatim on your Suse server for learning purposes. Be sure to back up the files that you overwrite first. I found Apache quite hard, starting from zero knowledge. You need to concentrate and maybe go over this a few times. I also found that clarity grew through worked examples.

Scenario: I illustrate Apache on a Suse workstation in a SOHO LAN with network communication between workstations. What I say here goes just as well for a single workstation serving pages to the web as it does for a SOHO LAN or a corporate LAN. All recipes have been tested on openSUSE 10.2, 10.3 and 11.0.

This tutorial is about installing the Apache web server and configuring it in some detail. It does allow you to carry your web server forward to the Internet to the point where you can address the public IP of your server externally and view the web content. The final step of viewing your web content by domain name needs only for you then to register your IP address in a Domain name Server and you'r complete.

If you haven't configured or arranged resolution of your domain name /s to IP address/es you may need some temporary, localised resolution for testing purposes. You can use the "hosts" file located at /etc/hosts to resolve www.swerdna.org to 192.168.10.44 on your server and around your LAN. Open the text file "hosts" on each computer, with a text editor and add the domain name/IP address pair on one line, so it looks like this:

127.0.0.1           localhost
192.168.10.44        www.swerdna.org
# special IPv6 addresses
etc..
etc..
192.168.10.33        susebox.swerdna susebox

OK, so one way or another your computers can now resolve www.swerdna.org to the Suse web server and you can now install the software.

Software: This is quite simple. Open Yast Software Management, change the LHS "search" option to "patterns" and select to install the Lamp server [Screenshot]. I suggest the LAMP server because although it has probably more than you need, it installs all that you could need with one click.

Basic Apache: To set up basic Apache server, go to Yast --> Network Services, activate "HTTP Server" and a wizard will take over to install the basic server. Make no special decisions except follow my screenshot #2 for scripting. Follow the prompts and Screenshot #2 to obtain a stock standard installation with capacity to script in PHP, Perl & Python . I have taken some screenshots for you in case you need them:

Suse: HTTP Server's first-run wizard
[Screenshot #1]  [Screenshot #2]  [Screenshot #3]  [Screenshot #4]  [Screenshot #5]

After you run the wizard, which is really a non event, make provision for the web server's administrator to be a user different from root. Two directories were installed along with the Apache software as containers for serving files via http and ftp, respectively /srv/ftp and /srv/www. They belong by default to root and you can/should change the ownership of the directories and their contents (recursively) to an ordinary user, e.g. suzette, with the chown command in a root console like this:

suzette@lampserver:~> su
Password:
lampserver:/home/suzette # chown -R suzette:users /srv/www
lampserver:/home/suzette # chown -R suzette:users /srv/ftp
lampserver:/home/suzette #

Start & stop Apache: You've configured Apache to start at boot. It should be running but check that with the shell command (issued as root) rcapache2 status which should return "running". If not use rcapache2 start. Other useful modifiers are restart and stop. If you want to check "start at boot" go to Yast --> System --> System Services --> Expert and check that Apache2 = runlevels 3 & 5.

Test Apache: With this essentially raw installation, you can address the web server by putting the IP address of the host in the address bar of a web client (e.g. Firefox, Konqueror, etc). So test with address http://192.168.10.44 from a client on the server itself and from a client on any other computer in the LAN. If you do get the "success" page from Apache then the installation succeeded. You'll find the self same html page in the server's filesystem at /srv/www/htdocs/index.html - check it out.

Main Configuration Files: There are quite a few Apache configuration files. I'll deal with these four in this tutorial:

  • httpd.conf for global directives; best left alone!
  • default-server.conf Overarching configuration for the various webs in the server
  • *.conf in /etc/apache2/vhosts.d: include files with Virtual Host configurations
  • .htaccess files, optionally one for each directory in the webspace filesystem

In this tutorial we're concerned with the last three, leaving the first alone.

default-server.conf controls the DocumentRoot located in Suse at /srv/www/htdocs. DocumentRoot is where you place your VirtualHosts, i.e. your website/s. Here's a link to the full file as installed by default in openSUSE 10.2/3. The next panel shows some extracts plus my commentory on those extracts:

# Here are some of the contents of the file default-server.conf, which is openSUSE 10.x's broad/global configuration file for Apache options.

line image

DocumentRoot "/srv/www/htdocs"

<Directory "/srv/www/htdocs">
Options None
AllowOverride None
Order allow,deny
Allow from all
</Directory>

ScriptAlias /cgi-bin/ "/srv/www/cgi-bin/"

<Directory "/srv/www/cgi-bin">
Options +ExecCGI -Includes
AllowOverride None
Order allow,deny
Allow from all
</Directory>

ServerName lampserver

line image

# Here are some explanatory comments:

# Directives for /srv/www/htdocs apply also in subdirectories i.e. server-wide

# Websites can be placed in & below the document root at /srv/www/htdocs

# The <Directory> ... </Directory> Directive marks the container for the group of directives which will apply only to the named directory and sub-directories of that directory

# The Options Directive controls which server features are available in a directory

# The AllowOverride Directive specifies the types of over-riding directives allowed in the .htaccess files in individual directories

# The Allow Directive controls which hosts can access this area of the server

# The ScriptAlias Directive here maps the webspace path /cgi-bin/ to the filesystem path /srv/www/cgi-bin/ and marks the directory as a containing CGI scripts

# Notice that these directives for the CGI directory use the confusing additive +/- syntax. In most cases the whole thing should be disabled (deleted) and CGI should be configured case by case within Virtual Server/s (example below).

# "lampserver" is this server's Linux hostname.

If you now put properly linked html documents in the directory htdocs you will have an elementary web server. Normally you wouldn't put your docs here. You'd put them in a more comprehensively configured Virtual Host as discussed next.

Virtual Hosts: The configuration you get installing Apache in Suse is nicely secure. I like to leave it alone to retain that and as a point of reference. Then I make changes to suit my needs in a separate configuration file that addresses the container (directory) where I put my site's html files. That's called a "virtual server" setup for a "virtual host".

There are two options, "name-based" or "IP-based". The latter is really for heavy duty sites. The name-based virtual host setup is the economy class product obtained from hosting companies. It allows many domain names to be served from the one IP address. It's efficient, economical and cuts down on the demand for IP addresses. I use it and speak about it here. There's a discussion of IP-based virtual hosts over at the Apache site. There is a bunch of examples of setups over there too, and I recommend that you look at them.

How Apache "Includes" Modular Configuration Files: In Suse the Virtual Servers/Hosts are configured in files ending with extensions .conf, located in the directory /etc/apache2/vhosts.d/. Any files ending with .conf in vhosts.d are "included" along with the main server configuration file (default-server.conf) and several other config files -- into the Apache config file httpd.conf. Apache builds its configuration in httpd.conf by "including" the various config modules when Apache starts. So you could just as easily put nothing in .conf files in directory vhosts.d, instead putting the information that would sit there directly into file default-server.conf. Indeed you could put the information from both of those files directly into httpd.conf BUT editing httpd.conf would invite disaster. It's better for new users to separate the broad server configuration into default-server.conf and the Virtual Host config into a separate file in vhosts.d directory.

Virtual Host setup for a single domain, e.g. www.swerdna.org: First declare to Apache that virtual hosting exists by adding this line into httpd.conf, indirectly via the included file default-server.conf; i.e. put it into default-server.conf:

# in file default-server.conf, implying the main server DocumentRoot

NameVirtualHost 192.168.10.44

# declares existence of virtual hosting on an IP address and implies default listening on port 80

Second declare the directory in the filesystem for the webspace document root of the virtual host with a configuration file named *.conf in the directory /etc/apache2/vhosts.d (call it anything you like that ends with .conf; e.g. here I'll use /etc/apache2/vhosts.d/vhost.conf).

# a <VirtualHost>...<VirtualHost> directive in file /etc/apache2/vhosts.d/vhost.conf declares and defines the web www.swerdna.org

<VirtualHost 192.168.10.44>
 DocumentRoot /srv/www/htdocs/swerdna.org
 servername www.swerdna.org
# additional directives here
</VirtualHost>

# use additional directives to override or supplement the server-wide, restrictive directives set earlier in "default-server.conf"

Now you can put your website files in the directory /srv/www/htdocs/swerdna.org, which you might recall is owned by the webmaster Suzette. After you restart Apache with rcapache2 restart, you can use the address http://www.swerdna.org to view the files in your browser from any networked computer. That's all you need to get a standard web server working, with static pages written in standard HTML or XHTML and with standard mime-types. Note that as currently set up, the web www.swerdna.org would inherit the directives Options None and AllowOverride None that were set up as defaults during the software installation. See next.

The Options Directive is set in the default Suse install of Apache to Options None upstream in directory htdocs, and inherited here. Here's what's implied by that:

AllowOverride Directive & the .htaccess file: You can have an .htaccess file in each directory to make configuration changes on a per-directory basis. What you can put in these files is determined by the AllowOverride directive. The default in Suse is AllowOverride None which disables the .htaccess configurations. On the other hand when you rent a hosting package you're likely to find complete flexibility for per-directory configuration has been enabled by setting AllowOverride All, which is the Apache default. That way the hosting companies don't have to worry about what users might do in the higher level configuration files.

Qualifiers other than "All" and "None" are available: see list just above and see Apache.org.

Virtual Host setup for multiple domains: If you want the server to respond to more than one domain you can add more files like vhost.conf, e.g. vhost_extra.conf, into directory /etc/apache2/vhosts.d and configure them similarly to the first (vhost.conf) but with changes appropriate to the names of the new domains. OR you could simply add the extra <VirtualHost>...</VirtualHost> configurations directly into the existing file vhost.conf, like this:

# this version of vhost.conf defines two domains with different webspaces on the server

<VirtualHost 192.168.10.44>
 DocumentRoot /srv/www/htdocs/swerdna.org
 servername www.swerdna.org
# additional directives for www.swerdna.org here
</VirtualHost>

<VirtualHost 192.168.10.44>
 DocumentRoot /srv/www/htdocs/computerhelp.com
 servername www.computerhelp.com
# additional directives for www.computerhelp.com here
</VirtualHost>

# the second website has its docs in directory /srv/www/htdocs/computerhelp.com

A Working Website, www.swerdna.org: I'll now tie together what I've said so far as a working website for www.swerdna.org. It's made up of the configuration files supplied by default in openSUSE plus your versions of default-server.conf and vhosts.conf. I'm leaving out CGI for now and will address that soon. Here is a working web configuration for static pages only, no SSI or CGI:

# /etc/apache2/default-server.conf
DocumentRoot "/srv/www/htdocs"
<Directory "/srv/www/htdocs">
 Options None
 AllowOverride None
 Order allow,deny
 Allow from all
</Directory>
ServerName lampserver
NameVirtualHost 192.168.10.44

# /etc/apache2/vhosts.d/vhost.conf
<VirtualHost 192.168.10.44>
 ServerName www.swerdna.org
 DocumentRoot /srv/www/htdocs/swerdna.org
 <Directory "/srv/www/htdocs/swerdna.org">
  Options None
  AllowOverride None
  Order allow,deny
  Allow from all
 </Directory>
</VirtualHost>

Server Side Includes: SSI deserves its own tutorial. Check out the excellent tutorial on the Apache site. There are two alternate ways to activate server side includes. Use one or the other, preferably not both. The preferred method sets SSI up in the Options Directive. The alternate method sets SSI up in the AllowOverride Directive plus .htaccess file.

Preferred activation method: You can activate SSI simply by allowing it in the Options Directive. Notice directly above in the <VirtualHost>...</VirtualHost> Directive we have Options None. You change that either to Options Includes or to Options All (because "All" includes "Includes").

Alternate activation method: If you rent webspace with a hosting company it's likely that you don't have access to key configuration files like default-server.conf and vhost.conf. It's also likely that support for the use of .htaccess files has been activated instead. This implies that the <VirtualHost>...</VirtualHost> Directive in vhosts.conf is set to Options None or at least omits the option Includes AND that the AllowOverride Directive is changed from AllowOverride None either to AllowOverride Options or to AllowOverride All (because "All" includes "Options"). Once that's done, goto the directory where you want to activate Server Side Includes (probably the document root for www.swerdna.org) and make sure it contains a file called .htaccess that contains the line Options Includes.

Now that you have Includes activated at the server level, you have to activate them also at the Page level. There are two alternate ways. One way is to activate the XBitHack Directive where pages are marked by turning on their execute bit to effect parsing for SSI. Below left is a Virtual Host setup where XBitHack is used to effect SSI. The second way is to give SSI-parsed pages a special extension, e.g. .shtml instead of .html and tell Apache to parse them by way of the AddType & AddHandler Directives. Below right is a Virtual Host setup where AddType .shtml is used to effect SSI. You aren't bound to use extension ".shtml". That's a common practice but any sensible extension works provided you let Apache know it's html with the AddType Directive.

# /etc/apache2/vhosts.d/vhost.conf
# Illustrates SSI by XBitHack
# Pages with user execute bit set will be parsed
# Set for entire webspace
<VirtualHost 192.168.10.44>
 ServerName www.swerdna.org
 DocumentRoot /srv/www/htdocs/swerdna.org
 <Directory "/srv/www/htdocs/swerdna.org">
  Options Includes
  XBitHack On
  AllowOverride None
  Order allow,deny
  Allow from all
 </Directory>
</VirtualHost>

# /etc/apache2/vhosts.d/vhost.conf
# Illustrates SSI by AddType and AddHandler
# Pages with extension .shtml will be parsed
# Set for entire webspace
<VirtualHost 192.168.10.44>
 ServerName www.swerdna.org
 DocumentRoot /srv/www/htdocs/swerdna.org
 <Directory "/srv/www/htdocs/swerdna.org">
  Options Includes
  AddType text/html .shtml
  AddHandler server-parsed .shtml
  AllowOverride None
  Order allow,deny
  Allow from all
 </Directory>
</VirtualHost>

Common Gateway Interface, CGI: CGI scripts are most commonly used to return "dynamic content" as HTML on execution of a script or other executable (e.g. compiled C, Fortran, Basic etc). CGI deserves a full tutorial in its own right and I refer you to the Apache site's CGI tutorial to get you started. You can effect the execution of an executable file three ways on an Apache server. To reduce confusion I'll lay them out quite separately. You'll need to prepare the scene with some text files that allow you to test your CGI setups. Create a directory called cgi-bin in the root of your www.swerdna.org web (i.e. at /cgi-bin in webspace or, same thing, at /srv/www/htdocs/swerdna.org/cgi-bin in filesystem space. Also prepare two text files with the contents including white space and names given below and put them in cgi-bin:

This is a shell script. Call it testcgi.sh, place it in directory cgi-bin and make it executable.
This is a perl script. Call it testcgi.pl, place it in directory cgi-bin and make it executable.
#!/bin/sh
echo "Content-type: text/html"
echo ""
echo "Hello World. Shell scripting works"
echo ""
#!/usr/bin/perl

print "Content-type: text/html\r\n\r\n";
print "<HTML>\n";
print "<HEAD><TITLE>Hello World!</TITLE></HEAD>\n";
print "<BODY>\n";
print "<H2>Perl script works</H2>\n";
print "</BODY>\n";
print "</HTML>\n";

exit (0);

Tip: If you change Apache's configuration when playing with these scripts and that should change what you see in your browser, but it doesn't, try clearing the browser's cache.

Alternative 1: CGI with the ScriptAlias Directive: This is the most familiar method. Make a directory in your webspace at /cgi-bin. In filesystem space this is the directory /srv/www/htdocs/swerdna.org/cgi-bin. Put the files in directory cgi-bin and make the two files executable using chmod a+x filename from a terminal open in directory cgi-bin. Now enable CGI scripting by inserting the ScriptAlias Directive into the Virtual Server configuration for www.swerdna.org, like so:

# /etc/apache2/vhosts.d/vhost.conf
# Illustrates CGI support enabling
# by adding ScriptAlias Directive
# CGI only in one web directory: /cgi-bin

<VirtualHost 192.168.10.44>
 ServerName www.swerdna.org
 DocumentRoot /srv/www/htdocs/swerdna.org
 ScriptAlias /cgi-bin/ /srv/www/htdocs/swerdna.org/cgi-bin/

 <Directory "/srv/www/htdocs/swerdna.org">
  Options None
  AllowOverride None
  Order allow,deny
  Allow from all
 </Directory>

 <Directory "/srv/www/htdocs/swerdna.org/cgi-bin">
  Options -Includes
  AllowOverride None
  Order allow,deny
  Allow from all
 </Directory>

</VirtualHost>

Note these important points regarding this configuration:

  • • The ScriptAlias Directive for cgi-bin is all that's necessary to ensure CGI support for scripting and executables is given to directory cgi-bin. Every executable file in cgi-bin that Suse supports becomes activated, regardless of the file extension. It is unnecessary to impose the AddHandler Directive or the ExecCGI Option in a <Directory> Directive for cgi-bin when ScriptAlias applies to it. ScriptAlias says it all.
  • • The <Directory> Directive for www.swerdna.org simply reiterates the configuration inherited from the upstream <Directory> Directive for htdocs, given in the configuration file default-server.conf. This time (this example only) the <Directory> Directive for swerdna.org is essentially a placeholder and an aide memoire. Having said that to make the situation clear, I also recommend always to leave it in for clarity & especially for debugging.
  • • Similarly in this example the <Directory> Directive for cgi-bin is not strictly necessary. CGI support would exist without this Directive. However it's necessary for clarity too.

You test this configuration by pointing your browser in any machine (with access to the server) to the address http://www.swerdna.org/cgi-bin/testcgi.sh [check here] or http://www.swerdna.org/cgi-bin/testcgi.pl [check here] and see if you get a positive result. Here's an additional experiment for you: make a second copy of the file testcgi.pl in /cgi-bin but with the name abcde. Make sure it's executable (chmod a+x abcde). Point your browser at http://www.swerdna.org/cgi-bin/abcde. You should get "Perl script works". Think about the security aspects of that!

Alternative 2: CGI with the Options Directive plus the AddHandler Directive: Another way to enable CGI is to use the Options Directive set to Options ExecCGI together with the AddHandler Directive. The AddHandler Directive lets you define just which files can be executed, whereas the "ScriptAlias" method above give blanket activation to all executables regardless of the file extension. Suppose there's a directory in webspace at /cgi-bin_2 where you want to make only perl scripts executable. You add ExecCGI and AddHandler into the <Directory> Directive for cgi-bin_2 in the vhosts.conf file, like this:

# /etc/apache2/vhosts.d/vhost.conf
# Illustrates CGI support enabled by adding
# Options ExecCGI and AddHandler Directives
# into the <Directory> Directive for /cgi-bin_2
# CGI only in one web directory: /cgi-bin_2
# Only perl scripts have been enabled (.pl)
<VirtualHost 192.168.10.44>
 ServerName www.swerdna.org
 DocumentRoot /srv/www/htdocs/swerdna.org

 <Directory "/srv/www/htdocs/swerdna.org">
  Options None
  AllowOverride None
  Order allow,deny
  Allow from all
 </Directory>

 <Directory "/srv/www/htdocs/swerdna.org/cgi-bin_2">
  Options +ExecCGI
  AddHandler cgi-script .pl
  AllowOverride None
  Order allow,deny
  Allow from all
 </Directory>

</VirtualHost>

This time only perl scripts can be executed, and others not until their extensions are included in the AddHandler Directive. Note that ExecCGI enables compiled executables that have no file extensions, like C, Fortran, Basic executables that need no scripting support. For these the AddHandler Directive isn't relevant.

Alternative 3: CGI with the AllowOverride Directive plus the .htaccess file: This method has performance overheads not found in alternatives 1 and 2. Alternatives 1 and 2 are recommended as preferred before this option in the Apache site's CGI tutorial. That wouldn't matter on a small site like www.swerdna.org. So to enable executable files in some directory e.g. /exec-dir in your webspace, set these in the <Directory>...</Directory> Directive: AllowOverride All and transfer Options and AddHandler to the .htaccess file in directory /exec-dir, like so:

# /etc/apache2/vhosts.d/vhost.conf
# Illustrates CGI support by moving
# AddHandler and Options ExecCGI
# to the .htaccess file

<VirtualHost 192.168.10.44>
ServerName www.swerdna.org
DocumentRoot /srv/www/htdocs/swerdna.org
<Directory "/srv/www/htdocs/swerdna.org">
  Options None
  AllowOverride None
  Order allow,deny
  Allow from all
</Directory>

<Directory "/srv/www/htdocs/swerdna.org/exec-dir">
  Options None
  AllowOverride All
  Order allow,deny
  Allow from all
</Directory>

</VirtualHost>
# file (webspace): /exec-dir/.htaccess
# ExecCGI enables executables
# AddHandler channels scripting support
Options +ExecCGI
AddHandler cgi-script .pl .sh

Going Public: You can already view the content on your SOHO Lan or corporate intranet in house by using the address http://www.swerdna.org. If you want to view the content from the general internet. There's a few simple final steps. You will have a router protecting your Lan from the internet. Open port forwarding and forward port 80 to the internal IP address of your web server. If you have an additional (personal) SuSEfirewall2 on your web server, in Yast firewall settings enable http as an allowed service for the external zone. At that point you can address your web server by the external IP address of your broadband connection (look in your router using your web browser if you've forgotten).

It took me such a long time to get this straight in my head and to work out the recipes I've put here. Hope it saves you some time.
Swerdna: 14 October 2007