httpd — Apache Web Server

webhostingguy 2,291 views 20 slides Apr 02, 2010
Slide 1
Slide 1 of 20
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20

About This Presentation

No description available for this slideshow.


Slide Content

Chapter36
httpd—ApacheWebServer
In this chapter, we will show how to set up a web server running virtual domains and
dynamic CGI web pages. HTML is not covered, and you are expected to have some
understanding of what HTML is, or at least where to nd documentation about it.
36.1 Web Server Basics
In Section 26.2 we showed a simple HTTP session with thetelnetcommand. A
web serveris really nothing more than a program that reads a le from the hard disk
whenever aGET /<filename>.html HTTP/1.0 request comes in on port 80. Here,
we will show a simple web server written in shell script.&Not by me. The author did not
put his name in the source, so if you are out there, please drop me an email.-You will need to add
the line
¨ ¥
www stream tcp nowait nobody /usr/local/sbin/sh-httpd
§ ¦
to your/etc/inetd.confle. If you are runningxinetd, then you will need to add
a le containing
¨ ¥
service www
{
socket_type = stream
wait = no
5 user = nobody
server = /usr/local/sbin/sh-httpd
}
§ ¦
to your/etc/xinetd.d/directory. Then, you must stop any already running web
servers and restartinetd(orxinetd).
389

36.1. Web Server Basics 36.
httpd — Apache Web Server
You will also have to create a log le (/usr/local/var/log/sh-httpd.log )
and at least one web page (/usr/local/var/sh-www/index.html ) for your server
to serve. It can contain, say:
¨ ¥
<HTML>
<HEAD>
<TITLE>My First Document</TITLE>
</HEAD>
5<BODY bgcolor=#CCCCCC text="#000000">
This is my first document<P>
Please visit
<A HREF="http://rute.sourceforge.net/">
The Rute Home Page
10 </A>
for more info.</P>
</BODY>
</HTML>
§ ¦
Note that the server runs asnobody, so the log le must be writable by theno-
bodyuser, and theindex.htmlle must be readable. Also note the use of theget-
peernamecommand, which can be changed toPEER=""if you do not have thenet-
pipespackage installed.&I am not completely sure if other commands used here are unavailable
on otherUNIXsystems.-.
¨ ¥
#!/bin/sh
VERSION=0.1
NAME="ShellHTTPD"
DEFCONTENT="text/html"
5DOCROOT=/usr/local/var/sh-www
DEFINDEX=index.html
LOGFILE=/usr/local/var/log/sh-httpd.log
log() {
10 local REMOTE_HOST=$1
local REFERRER=$2
local CODE=$3
local SIZE=$4
15 echo "$REMOTE_HOST $REFERRER - [$REQ_DATE] \
\"${REQUEST}\" ${CODE} ${SIZE}" >> ${LOGFILE}
}
print_header() {
20 echo -e "HTTP/1.0 200 OK"
echo -e "Server: ${NAME}/${VERSION}"
echo -e "Date: `date`"
}
25print_error() {
echo -e "HTTP/1.0 $1 $2"
390

36.
httpd — Apache Web Server 36.1. Web Server Basics
echo -e "Content-type: $DEFCONTENT"
echo -e "Connection: close"
echo -e "Date: `date`"
30 echo -e ""
echo -e "$2"
exit 1
}
35guess_content_type() {
local FILE=$1
local CONTENT
case ${FILE##*.} in
40 html) CONTENT=$DEFCONTENT ;;
gz) CONTENT=application/x-gzip ;;
*) CONTENT=application/octet-stream ;;
esac
45 echo -e "Content-type: $CONTENT"
}
do_get() {
local DIR
50 local NURL
local LEN
if [ ! -d $DOCROOT ]; then
log ${PEER} - 404 0
55 print_error 404 "No such file or directory"
fi
if [ -z "${URL##*/}" ]; then
URL=${URL}${DEFINDEX}
60 fi
DIR="`dirname $URL`"
if [ ! -d ${DOCROOT}/${DIR} ]; then
log ${PEER} - 404 0
65 print_error 404 "Directory not found"
else
cd ${DOCROOT}/${DIR}
NURL="`pwd`/`basename ${URL}`"
URL=${NURL}
70 fi
if [ ! -f ${URL} ]; then
log ${PEER} - 404 0
print_error 404 "Document not found"
75 fi
print_header
guess_content_type ${URL}
LEN="`ls -l ${URL} | tr -s ' ' | cut -d ' ' -f 5`"
80 echo -e "Content-length: $LEN"
log ${PEER} - 200 ${LEN}
391

36.1. Web Server Basics 36.
httpd — Apache Web Server
cat ${URL}
sleep 3
}
85
read_request() {
local DIRT
local COMMAND
90 read REQUEST
read DIRT
REQ_DATE="`date +"%d/%b/%Y:%H:%M:%S %z"`"
REQUEST="`echo ${REQUEST} | tr -s [:blank:]`"
95 COMMAND="`echo ${REQUEST} | cut -d ' ' -f 1`"
URL="`echo ${REQUEST} | cut -d ' ' -f 2`"
PROTOCOL="`echo ${REQUEST} | cut -d ' ' -f 3`"
case $COMMAND in
100 HEAD)
print_error 501 "Not implemented (yet)"
;;
GET)
do_get
105 ;;
*)
print_error 501 "Not Implemented"
;;
esac
110}
#
# It was supposed to be clean - without any non-standard utilities
# but I want some logging where the connections come from, so
115# I use just this one utility to get the peer address
#
# This is from the netpipes package
PEER="`getpeername | cut -d ' ' -f 1`"
120read_request
exit 0
§ ¦
Now runtelnet localhost 80, as in Section 26.2. If that works and your
log les are being properly appended (usetail -f. . . ), you can try to connect to
http://localhost/with a web browser like Netscape.
Notice also that the commandgetsockname(which tells you which of your own
IP addresses the remote client connected to) could allow the script to serve pages from
a different directory for each IP address. This isvirtual domainsin a nutshell.&Groovy,
baby, I'm in a giant nutshell.... how do I get out?-
392

36.
httpd — Apache Web Server 36.2. Installing and Conguring Apache
36.2 Installing and Conguring Apache
Because all distributions package Apache in a different way, here I assume Apache
to have been installed from its source tree, rather than from a.debor.rpm
package. You can refer to Section 24.1 on how to install Apache from its source
.tar.gzle like any other GNU package. (You can even install it under Win-
dows, Windows NT, or OS/2.) The source tree is, of course, available fromThe
Apache Home Pagehttp://www.apache.org. Here I assume you have installed it in--
prefix=/opt/apache/. In the process, Apache will have dumped a huge reference
manual into/opt/apache/htdocs/manual/ .
36.2.1 Samplehttpd.conf
Apache has several legacy conguration les:access.confandsrm.confare two
of them. These les are now deprecated and should be left empty. A single congura-
tion le/opt/apache/conf/httpd.conf may contain at minimum:
¨ ¥
ServerType standalone
ServerRoot "/opt/apache"
PidFile /opt/apache/logs/httpd.pid
ScoreBoardFile /opt/apache/logs/httpd.scoreboard
5Port 80
User nobody
Group nobody
HostnameLookups Off
ServerAdmin [email protected]
10UseCanonicalName On
ServerSignature On
DefaultType text/plain
ErrorLog /opt/apache/logs/error_log
LogLevel warn
15LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog /opt/apache/logs/access_log common
DocumentRoot "/opt/apache/htdocs"
DirectoryIndex index.html
AccessFileName .htaccess
20<Directory />
Options FollowSymLinks
AllowOverride None
Order Deny,Allow
Deny from All
25</Directory>
<Files ˜ "ˆ\.ht">
Order allow,deny
Deny from all
</Files>
30<Directory "/opt/apache/htdocs">
Options Indexes FollowSymLinks MultiViews
AllowOverride All
393

36.2. Installing and Conguring Apache 36.
httpd — Apache Web Server
Order allow,deny
Allow from all
35</Directory>
<Directory "/opt/apache/htdocs/home/*/www">
Options Indexes MultiViews
AllowOverride None
Order allow,deny
40 Allow from all
</Directory>
UserDir /opt/apache/htdocs/home/*/www
§ ¦
With the cong le ready, you can move theindex.htmlle above to
/opt/apache/htdocs/. You will notice the complete Apache manual and a demo
page already installed there; you can move them to another directory for the time be-
ing. Now run
¨ ¥
/opt/apache/bin/httpd -X
§ ¦
and then point your web browser tohttp://localhost/as before.
36.2.2 Common directives
Here is a description of the options. Each option is called a directive
in Apache terminology. A complete list of basic directives is in the le
/opt/apache/htdocs/manual/mod/core.html .
ServerTypeAs discussed in Section 29.2, some services can run standalone or from
inetd(orxinetd). This directive can be exactlystandaloneorinetd. If
you chooseinetd, you will need to add an appropriate line into yourinetd
conguration, although a web server should almost certainly choose standalone
mode.
ServerRootThis is the directory superstructure&See page 137.-under which Apache
is installed. It will always be the same as the value passed to--prefix=.
PidFileMany system services store the process ID in a le for shutdown and moni-
toring purposes. On most distributions, the le is/var/run/httpd.pid.
ScoreBoardFileThis option is used for communication between Apache parent
and child processes on some non-UNIXsystems.
PortThis is the TCP port for standalone servers to listen on.
User,GroupThis option is important for security. It forceshttpdto usernobody
privileges. If the web server is ever hacked, the attack will not be able to gain
more than the privileges of thenobodyuser.
394

36.
httpd — Apache Web Server 36.2. Installing and Conguring Apache
HostnameLookupsTo force a reverse DNS lookup on every connecting host, set this
directive toon. To force a forward lookup on every reverse lookup, set this to
double. This option is for logging purposes since access control does a reverse
and forward reverse lookup anyway if required. It should certainly beoffif you
want to reduce latency.
ServerAdminError messages include this email address.
UseCanonicalName If Apache has to return a URL for any reason, it will normally
return the full name of the server. Setting tooffuses the very host name sent by
the client.
ServerSignatureAdd the server name to HTML error messages.
DefaultTypeAll les returned to the client have a type eld specifying how the le
should be displayed. If Apache cannot deduce the type, it assumes the MIME
Type to betext/plain. See Section 12.6.2 for a discussion of MIME types.
ErrorLogWhere errors get logged, usually/var/log/httpd/error log
LogLevelHow much info to log.
LogFormatDene a new log format. Here we dened a log format and call itcom-
mon. Multiple lines are allowed. Lots of interesting information can actually
be logged: See/opt/apache/htdocs/manual/mod/mod logconfig.html
for a full description.
CustomLogThe log le name and its (previously dened) format.
DocumentRootThis directive species the top-level directory that client connec-
tions will see. The string/opt/apache/htdocs/ is prepended to any le
lookup, and hence a URLhttp://localhost/manual/index.html.enwill return the le
/opt/apache/htdocs/manual/index.html.en .
DirectoryIndexThis directive gives the default le to try serve for URLs that con-
tain only a directory name. If a leindex.htmldoes not exist under that direc-
tory, an index of the directory is sent to the client. Other common congurations
useindex.htmordefault.html.
AccessFileNameBefore serving a le to a client, Apache reads additional directives
from a le.htaccessin the same directory as the requested le. If a parent
directory contains a.htaccessinstead, this one will take priority. The.htac-
cessle contains directives that limit access to the directory, as discussed below.
The above is merely the general conguration of Apache. To actually serve pages,
you need to dene directories, each with a particular purpose, containing particular
HTML or graphic les. The Apache conguration le is very much like an HTML
document. Sections are started with<section parameter>and ended with</section>.
395

36.2. Installing and Conguring Apache 36.
httpd — Apache Web Server
The most common directive of this sort is<Directory /directory>which does such
directory denition. Before dening any directories, we need to limit access to the root
directory. This control is critical for security.
¨ ¥
<Directory />
Options FollowSymLinks
Deny from All
Order Deny,Allow
5 AllowOverride None
</Directory>
§ ¦
This conguration tells Apache about the root directory, giving clients very restrictive
access to it. The directives are&Some of these are extracted from the Apache manual.-:
OptionsTheOptionsdirective controls which server features are available in a par-
ticular directory. There is also the syntax+optionor-optionto include the options
of the parent directory, for example,Options +FollowSymLinks -Indexes .
FollowSymLinksThe server will follow any symbolic links beneath the direc-
tory. Be careful about what symbolic links you have beneath directories with
FollowSymLinks. You can, for example, give everyone access to the root
directory by having a link../../../underhtdocs—not what you want.
ExecCGIExecution of CGI scripts is permitted.
IncludesServer-side includes are permitted (more on this later).
IncludesNOEXECServer-side includes are permitted, but the#execcommand
and#includeof CGI scripts are disabled.
IndexesIf a client asks for a directory by name and noindex.htmlle (or
whateverDirectoryIndexle you specied) is present, then a pretty list-
ing of the contents of that directory is created and returned. For security
you may want to turn this option off.
MultiViewsContent-negotiated MultiViews are allowed (more on this later).
SymLinksIfOwnerMatch The server will only follow symbolic links for which
the target le or directory is owned by the same user ID as the link (more on
this later).
AllAll options except forMultiViews. This is the default setting.
DenyHosts that are not allowed to connect. You can specify a host name or IP address,
for example, as:
¨ ¥
Deny from 10.1.2.3
Deny from 192.168.5.0/24
Deny from cranzgot.co.za
§ ¦
396

36.
httpd — Apache Web Server 36.2. Installing and Conguring Apache
which will deny access to10.1.2.3, all hosts beginning with192.168.5., and
all hosts ending in.cranzgot.co.za, including the hostcranzgot.co.za.
AllowHosts that are allowed to connect. This directive uses the same syntax asDeny.
OrderIf order isDeny,Allow, then theDenydirectives are checked rst and any
client that does not match aDenydirective or does match anAllowdirective
will beallowedaccess to the server.
If order isAllow,Deny, then theAllowdirectives are checked rst and any
client that does not match anAllowdirective or does match aDenydirective
will bedeniedaccess to the server.
AllowOverrideIn addition to the directives specied here, additional directives will
be read from the le specied byAccessFileName, usually called.htac-
cess. This le would usually exist alongside your.htmlles or otherwise
in a parent directory. If the le exists, its contents are read into the cur-
rent<Directory. . .>directive.AllowOverridesays what directives the
.htaccessle is allowed to squash. The complete list can be found in
/opt/apache/htdocs/manual/mod/core.html .
You can see that we give very restrictiveOptionsto the root directory, as well
as very restrictive access. The only server feature we allow isFollowSymLinks, then
weDenyany access, and then we remove the possibility that a.htaccessle could
override our restrictions.
The<Files. . .>directive sets restrictions on all les matching a particular reg-
ular expression. As a security measure, we use it to prevent access to all.htaccess
les as follows:
¨ ¥
<Files ˜ "ˆ\.ht">
Order allow,deny
Deny from all
</Files>
§ ¦
We are now nally ready to add actual web page directories. These take a less
restrictive set of access controls:
¨ ¥
<Directory "/opt/apache/htdocs">
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
5 Allow from all
</Directory>
§ ¦
397

36.2. Installing and Conguring Apache 36.
httpd — Apache Web Server
36.2.3 User HTML directories
Our users may require that Apache know about their private web page directories
˜/www/. This is easy to support with the specialUserDirdirective:
¨ ¥
<Directory "/opt/apache/htdocs/home/*/www">
Options Indexes MultiViews
AllowOverride None
Order allow,deny
5 Allow from all
</Directory>
UserDir /opt/apache/htdocs/home/*/www
§ ¦
For this feature to work, you must symlink /opt/apache/htdocs/home
to/home, and create a directorywww/under each user's home direc-
tory. Hitting the URL http://localhost/˜jack/index.htmlwill then retrieve the le
/opt/apache/htdocs/home/jack/www/index.html . You will nd that Apache
gives aForbiddenerror message when you try to do this. This is probably because
jack's home directory's permissions are too restrictive. Your choices vary between
now makingjack's home directory less restricted or increasing the privileges of
Apache. Running Apache under thewwwgroup by usingGroup www, and then
running
¨ ¥
groupadd -g 65 www
chown jack:www /home/jack /home/jack/www
chmod 0750 /home/jack /home/jack/www
§ ¦
is a reasonable compromise.
36.2.4 Aliasing
Sometimes, HTML documents will want to refer to a le or graphic by using a simple
prex, rather than a long directory name. Other times, you want two different refer-
ences to source the same le. TheAliasdirective creates virtual links between direc-
tories. For example, adding the following line, means that a URL/icons/bomb.gif
will serve the le/opt/apache/icons/bomb.gif :
¨ ¥
Alias /icons/ "/opt/apache/icons/"
§ ¦
We do, of course, need to tell Apache about this directory:
¨ ¥
<Directory "/opt/apache/icons">
Options None
AllowOverride None
Order allow,deny
398

36.
httpd — Apache Web Server 36.2. Installing and Conguring Apache
5 Allow from all
</Directory>
§ ¦
36.2.5 Fancy indexes
You will nd the directory lists generated by the preceding conguration rather bland.
The directive
¨ ¥
IndexOptions FancyIndexing
§ ¦
causes nice descriptive icons to be printed to the left of the le name. What icons match
what le types is a trick issue. You can start with:
¨ ¥
AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
AddIconByType (TXT,/icons/text.gif) text/*
AddIconByType (IMG,/icons/image2.gif) image/*
AddIconByType (SND,/icons/sound2.gif) audio/*
5AddIconByType (VID,/icons/movie.gif) video/*
AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
AddIcon /icons/a.gif .ps .eps
AddIcon /icons/layout.gif .html .shtml .htm
§ ¦
This requires theAliasdirective above to be present. The default Apache congura-
tion contains a far more extensive map of le types.
36.2.6 Encoding and language negotiation
You can get Apache to servegzipped les with this:
¨ ¥
AddEncoding x-compress Z
AddEncoding x-gzip gz
§ ¦
Now if a client requests a leindex.html, but only a leindex.html.gzexists,
Apache decompresses it on-the-y. Note that you must have theMultiViewsoptions
enabled.
The next options cause Apache to serveindex.html.language-codewhenin-
dex.htmlis requested, lling in the preferred language code sent by the web browser.
Adding these directives causes your Apache manual to display correctly and will prop-
erly show documents that have non-English translations. Here also, theMultiViews
must be present.
¨ ¥
AddLanguage en .en
399

36.2. Installing and Conguring Apache 36.
httpd — Apache Web Server
AddLanguage da .dk
AddLanguage nl .nl
AddLanguage et .ee
5AddLanguage fr .fr
AddLanguage de .de
AddLanguage el .el
AddLanguage ja .ja
AddLanguage ru .ru
10LanguagePriority en da nl et fr de el ja ru
§ ¦
TheLanguagePrioritydirective indicates the preferred language if the browser did
not specify any.
Some les might contain a.koi8-rextension, indicating a Russian character set
encoding for this le. Many languages have such custom character sets. Russian les
are namedwebpage.html.ru.koi8-r. Apache must tell the web browser about the
encoding type, based on the extension. Here are directives for Japanese, Russian, and
UTF-8&UTF-8 is a Unicode character set encoding useful for any language.-, as follows:
¨ ¥
AddCharset ISO-2022-JP .jis
AddCharset KOI8-R .koi8-r
AddCharset UTF-8 .utf8
§ ¦
Once again, the default Apache conguration contains a far more extensive map
of languages and character sets.
36.2.7 Server-side includes — SSI
Apache actually has a built-in programming language that interprets.shtmlles as
scripts. The output of such a script is returned to the client. Most of a typical.shtml
le will be ordinary HTML, which will be served unmodied. However, lines like
¨ ¥
<!--#echo var="DATE_LOCAL" -->
§ ¦
will be interpreted, and their outputincludedinto the HTML—hence the nameserver-
side includes. Server-side includes are ideal for HTML pages that contain mostly static
HTML with small bits of dynamic content. To demonstrate, add the following to your
httpd.conf:
¨ ¥
AddType text/html .shtml
AddHandler server-parsed .shtml
<Directory "/opt/apache/htdocs/ssi">
Options Includes
5 AllowOverride None
Order allow,deny
400

36.
httpd — Apache Web Server 36.2. Installing and Conguring Apache
Allow from all
</Directory>
§ ¦
Create a directory/opt/apache/htdocs/ssi with the index leindex.shtml:
¨ ¥
<HTML>
The date today is <!--#echo var="DATE_LOCAL" -->.<P>
Here is a directory listing:<br>
<PRE>
5 <!--#exec cmd="ls -al" -->
</PRE>
<!--#include virtual="footer.html" -->
</HTML>
§ ¦
and then a lefooter.htmlcontaining anything you like. It is obvious how useful
this procedure is for creating many documents with the same banner by means of a
#includestatement. If you are wondering what other variables you can print besides
DATELOCAL, try the following:
¨ ¥
<HTML>
<PRE>
<!--#printenv -->
</PRE>
5</HTML>
§ ¦
You can also gotohttp://localhost/manual/howto/ssi.htmlto see some other examples.
36.2.8 CGI — Common Gateway Interface
(I have actually never managed to gure out why CGI is called CGI.) CGI is where
a URL points to a script. What comes up in your browser is the output of the script
(were it to be executed) instead of the contents of the script itself. To try this, create a
le/opt/apache/htdocs/test.cgi :
¨ ¥
#!/bin/sh
echo 'Content-type: text/html'
echo
5echo '<HTML>'
echo ' <HEAD>'
echo ' <TITLE>My First CGI</TITLE>'
echo ' </HEAD>'
echo ' <BODY bgcolor=#CCCCCC text="#000000">'
10echo 'This is my first CGI<P>'
echo 'Please visit'
401

36.2. Installing and Conguring Apache 36.
httpd — Apache Web Server
echo ' <A HREF="http://rute.sourceforge.net/">'
echo ' The Rute Home Page'
echo ' </A>'
15echo 'for more info.</P>'
echo ' </BODY>'
echo '</HTML>'
§ ¦
Make this script executable withchmod a+x test.cgi and test the output by
running it on the command-line. Add the line
¨ ¥
AddHandler cgi-script .cgi
§ ¦
to yourhttpd.confle. Next, modify your Optionsfor the directory
/opt/apache/htdocs to includeExecCGI, like this:
¨ ¥
<Directory "/opt/apache/htdocs">
Options Indexes FollowSymLinks MultiViews ExecCGI
AllowOverride All
Order allow,deny
5 Allow from all
</Directory>
§ ¦
After restarting Apache you should be able to visit the URLhttp://localhost/test.cgi.
If you run into problems, don't forget to runtail /opt/apache/logs/error log
to get a full report.
To get a full list of environment variables available to your CGI program, try the
following script:
¨ ¥
#!/bin/sh
echo 'Content-type: text/html'
echo
5echo '<HTML>'
echo '<PRE>'
set
echo '</PRE>'
echo '</HTML>'
§ ¦
The script will show ordinarybashenvironment variables as well as more interesting
variables likeQUERYSTRING: Change your script to
¨ ¥
#!/bin/sh
echo 'Content-type: text/html'
echo
402

36.
httpd — Apache Web Server 36.2. Installing and Conguring Apache
5echo '<HTML>'
echo '<PRE>'
echo $QUERY_STRING
echo '</PRE>'
echo '</HTML>'
§ ¦
and then go to the URLhttp://localhost/test/test.cgi?xxx=2&yyy=3. It is easy to see how
variables can be passed to the shell script.
The preceding example is not very interesting. However, it gets useful when
scripts have complex logic or can access information that Apache can't access on its
own. In Chapter 38 we see how to deploy an SQL database. When you have covered
SQL, you can come back here and replace your CGI script with,
¨ ¥
#!/bin/sh
echo 'Content-type: text/html'
echo
5
psql -d template1 -H -c "SELECT * FROM pg_tables;"
§ ¦
This script will dump the table list of thetemplate1database if it exists. Apache will
have to run as a user that can access this database, which means changingUser no-
bodytoUser postgres.&Note that for security you shouldreallylimit who can connect to the
postgresdatabase. See Section 38.4.-
36.2.9 Forms and CGI
To create a functional form, use the HTTP<FORM>tag as follows. A le
/opt/apache/htdocs/test/form.html could contain:
¨ ¥
<HTML>
<FORM name="myform" action="test.cgi" method="get">
<TABLE>
<TR>
5 <TD colspan="2" align="center">
Please enter your personal details:
</TD>
</TR>
<TR>
10 <TD>Name:</TD><TD><INPUT type="text" name="name"></TD>
</TR>
<TR>
<TD>Email:</TD><TD><INPUT type="text" name="email"></TD>
</TR>
15 <TR>
403

36.2. Installing and Conguring Apache 36.
httpd — Apache Web Server
<TD>Tel:</TD><TD><INPUT type="text" name="tel"></TD>
</TR>
<TR>
<TD colspan="2" align="center">
20 <INPUT type="submit" value="Submit">
</TD>
</TR>
</TABLE>
</FORM>
25</HTML>
§ ¦
which looks like:
Note how this form calls our existingtest.cgiscript. Here is a script that adds
the entered data to apostgresSQL table:
¨ ¥
#!/bin/sh
echo 'Content-type: text/html'
echo
5
opts=`echo "$QUERY_STRING" | \
sed -e 's/[ˆA-Za-z0-9 %&+,.\/:=@_˜-]//g' -e 's/&/ /g' -e q`
for opt in $opts ; do
10 case $opt in
name=*)
name=${opt/name=/}
;;
email=*)
15 email=${opt/email=/}
;;
tel=*)
tel=${opt/tel=/}
;;
20 esac
404

36.
httpd — Apache Web Server 36.2. Installing and Conguring Apache
done
if psql -d template1 -H -c "\
INSERT INTO people (name, email, tel) \
25VALUES ('$name', '$email', '$tel')" 2>&1 | grep -q 'ˆINSERT ' ; then
echo "<HTML>Your details \"$name\", \"$email\" and \"$tel\"<BR>"
echo "have been succesfully recorded.</HTML>"
else
echo "<HTML>Database error, please contact our webmaster.</HTML>"
30fi
exit 0
§ ¦
Note how the rst lines of script remove all unwanted characters from
QUERYSTRING. Such processing is imperative for security because shell scripts can
easily execute commands should characters like$and`be present in a string.
To use the alternative “POST” method, change yourFORMtag to
¨ ¥
<FORM name="myform" action="test.cgi" method="post">
§ ¦
The POST method sends the query text through stdin of the CGI script. Hence, you
need to also change youropts=line to
¨ ¥
opts=`cat | \
sed -e 's/[ˆA-Za-z0-9 %&+,.\/:=@_˜-]//g' -e 's/&/ /g' -e q`
§ ¦
36.2.10 Setuid CGIs
Running Apache as a privileged user has security implications. Another way to get
this script to execute as userpostgresis to create a setuid binary. To do this, create a
letest.cgiby compiling the followingC program similar to that in Section 33.2.
¨ ¥
#include <unistd.h>
int main (int argc, char *argv[])
{
5 setreuid (geteuid (), geteuid ());
execl ("/opt/apache/htdocs/test/test.sh", "test.sh", 0);
return 0;
}
§ ¦
405

36.2. Installing and Conguring Apache 36.
httpd — Apache Web Server
Then runchown postgres:www test.cgi andchmod a-w,o-rx,u+s
test.cgi(orchmod 4550 test.cgi). Recreate your shell script astest.shand
go to the URL again. Apache runstest.cgi, which becomes userpostgres, and
then executes the script as thepostgresuser. Even with Apache asUser nobody
your script will still work. Note how your setuid program is insecure: it takes no ar-
guments and performs only a single function, but it takes environment variables (or
input from stdin) that could inuence its functionality. If a login user could execute
the script, that user could send data via these variables that could cause the script to
behave in an unforeseen way. An alternative is:
¨ ¥
#include <unistd.h>
int main (int argc, char *argv[])
{
5 char *envir[] = {0};
setreuid (geteuid (), geteuid ());
execle ("/opt/apache/htdocs/test/test.sh", "test.sh", 0, envir);
return 0;
}
§ ¦
This script nullies the environment before starting the CGI, thus forcing you to use
the POST method only. Because the only information that can be passed to the script
is a single line of text (through the-e qoption tosed) and because that line of text is
carefully stripped of unwanted characters, we can be much more certain of security.
36.2.11 Apache modules and PHP
CGI execution is extremely slow if Apache has to invoke a shell script for each hit.
Apache has a number of facilities for built-in interpreters that will parse script les
with high efciency. A well-known programming language developed specically
for the Web is PHP. PHP can be downloaded as source fromThe PHP Home Page
http://www.php.netand contains the usual GNU installation instructions.
Apache has the facility for adding functionality at runtime using what it calls
DSO (Dynamic Shared Object) les. This feature is for distribution vendors who want
to ship split installs of Apache that enable users to install only the parts of Apache
they like. This is conceptually the same as what we saw in Section 23.1: To give your
program some extra feature provided by some library, you caneitherstatically link
the library to your programorcompile the library as a shared.sole to be linked
at run time. The difference here is that the library les are (usually) calledmodname
and are stored in/opt/apache/libexec/ . They are also only loaded if aLoad-
Modulenamemoduleappears inhttpd.conf. To enable DSO support, rebuild and
reinstall Apache starting with:
¨ ¥
./configure --prefix=/opt/apache --enable-module=so
§ ¦
406

36.
httpd — Apache Web Server 36.2. Installing and Conguring Apache
Any source package that creates an Apache module can now use the Apache
utility/opt/apache/bin/apxs to tell it about the current Apache installation, so
you should make sure this executable is in yourPATH.
You can now follow the instructions for installing PHP, possibly beginning with
./configure --prefix=/opt/php --with-apxs=/opt/apache/bin/apxs
--with-pgsql=/usr. (This assumes that you want to enable support for the
postgresSQL database and havepostgrespreviously installed as a pack-
age under/usr.) Finally, check that a lelibphp4.soeventually ends up in
/opt/apache/libexec/.
Yourhttpd.confthen needs to know about PHP scripts. Add the following
lines
¨ ¥
LoadModule php4_module /opt/apache/libexec/libphp4.so
AddModule mod_php4.c
AddType application/x-httpd-php .php
§ ¦
and then create a le/opt/apache/htdocs/hello.php containing
¨ ¥
<html>
<head>
<title>Example</title>
</head>
5<body>
<?php echo "Hi, I'm a PHP script!"; ?>
</body>
</html>
§ ¦
and test by visiting the URLhttp://localhost/hello.php.
Programming in the PHP language is beyond the scope of this book.
36.2.12 Virtual hosts
Virtual hosting is the use of a single web server to serve the web pages of multiple
domains. Although the web browser seems to be connecting to a web site that is an
isolated entity, that web site may in fact be hosted alongside many others on the same
machine.
Virtual hosting is rather trivial to congure. Let us say that we have three
domains:www.domain1.com,www.domain2.com, andwww.domain3.com. We
want domainswww.domain1.com andwww.domain2.com to share IP address
196.123.45.1, whilewww.domain3.comhas its own IP address of196.123.45.2.
The sharing of a single IP address is calledname-based virtual hosting, and the use of a
different IP address for each domain is calledIP-based virtual hosting.
407

36.2. Installing and Conguring Apache 36.
httpd — Apache Web Server
If our machine has one IP address,196.123.45.1, we may need to congure a
separate IP address on the same network card as follows (see Section 25.9):
¨ ¥
ifconfig eth0:1 196.123.45.2 netmask 255.255.255.0 up
§ ¦
For each domain/opt/apache/htdocs/www.domain ?.com/, we now create a
top-level directory. We need to tell Apache that we intend to use the IP address
196.123.45.1for several hosts. We do that with theNameVirtualHostdirective.
Then for each host, we must specify a top-level directory as follows:
¨ ¥
NameVirtualHost 196.123.45.1
<VirtualHost 196.123.45.1>
ServerName www.domain1.com
5 DocumentRoot /opt/apache/htdocs/www.domain1.com/
</VirtualHost>
<VirtualHost 196.123.45.1>
ServerName www.domain2.com
10 DocumentRoot /opt/apache/htdocs/www.domain2.com/
</VirtualHost>
<VirtualHost 196.123.45.2>
ServerName www.domain3.com
15 DocumentRoot /opt/apache/htdocs/www.domain3.com/
</VirtualHost>
§ ¦
All that remains is to congure a correct DNS zone for each domain so that lookups of
www.domain1.comandwww.domain2.comreturn196.123.45.1while lookups
ofwww.domain3.comreturn196.123.45.2.
You can then addindex.htmlles to each directory.
408