This configuration is based on Beyond Linux From Scratch 6.2, and causes Apache to run its slave processes under the unprivileged user "apache". The "expat", "ssl", "pcre" and "z" parameters to configure tells Apache to use the versions which are already installed. The file /etc/rc.d/init.d/apache is the script used to start and stop Apache.mount -wo remount / cd /usr/src tar -xjf httpd-2.2.2.tar.bz2 cd httpd-2.2.2 groupadd -g 25 apache useradd -c "Apache Server" -d /dev/null -g apache -s /bin/false -u 25 apache (patch -Np1 -i ../httpd-2.2.2-config-1.patch) 2>&1 | tee -a ../apache.out (./configure --enable-layout=FHS --enable-mods-shared=all --with-expat=/usr --enable-ssl --with-pcre --with-z) 2>&1 | tee -a ../apache.out (make) 2>&1 | tee -a ../apache.out (make install) 2>&1 | tee -a ../apache.out chown -v root:root /usr/lib/apache/httpd.exp \ /usr/sbin/{apxs,apachectl,dbmmanage,envvars{,-std}} \ /usr/share/man/man1/{dbmmanage,ht{dbm,digest,passwd}}.1 \ /usr/share/man/man8/{ab,apachectl,apxs,htcacheclean,httpd}.8 \ /usr/share/man/man8/{logresolve,rotatelogs,suexec}.8 && chown -v -R apache:apache /srv/www sed -i -e "s/User daemon/User apache/" -e "s/Group daemon/Group apache/" /etc/apache/httpd.conf cd /sources/blfs-bootscripts-20060910/ make install-apache cd mount -ro remount /The patch makes a small change in the configuration parameters.
defaults for all directories:(AllowOverride None indicates that options may not be overridden by .htaccess files)< Directory /> Options FollowSymLinks AllowOverride None </Directory>
default: /var/log/apache/error_log
default: warn
default: On
default: 5
default: all
default: 100
default: 80
default: 300
default: /srv/www/htdocs
Error Number meaning 100 Continue 101 Switching Protocols 200 OK 201 Created 202 Accepted 203 Non-Authoritative Information 204 No Content 205 Reset Content 206 Partial Content 300 Multiple Choices 301 Moved Permanently 302 Found 303 See Other 304 Not Modified 305 Use Proxy 306 (Unused) 307 Temporary Redirect 400 Bad Request 401 Unauthorized 402 Payment Required 403 Forbidden 404 Not Found 405 Method Not Allowed 406 Not Acceptable 407 Proxy Authentication Required 408 Request Timeout 409 Conflict 410 Gone 411 Length Required 412 Precondition Failed 413 Request Entity Too Large 414 Request-URI Too Long 415 Unsupported Media Type 416 Requested Range Not Satisfiable 417 Expectation Failed 500 Internal Server Error 501 Not Implemented 502 Bad Gateway 503 Service Unavailable 504 Gateway Timeout 505 HTTP Version Not Supported
options include ExecCGI, FollowSymLinks, IndexesNote that FollowSymLinks and Indexes are on by default if no Options directives apply; if you want to turn them off, you must either use the Options -FollowSymLinks and/or -Indexes directives, or use an Options None directive. It is probably most convenient to put the Options None directive in the default directory scope (<Directory />), and then turn on any desired options in individual directories.Any CGI script not in the "ScriptAlias directory" must be in a directory with the option ExecCGI turned on.
for example, to deny access to anyone except my.pc.at.foo.com:order deny,allow
deny from all
allow from my.pc.at.foo.com
default: 256
default: /etc/apache
default: 5
path?fieldname1=value&fieldname2=value(path? is stripped off)
Data validation is extremely important in CGI! This is how most web server attacks are made: invalid form data (ie., embedded SQL commands) that is not rejected may end up getting executed if the CGI program is stupid enough.
GET method is used to retrieve information (ordinary web requests, or from forms such as the one below)
In a POST request, information is processed by the server, but no reply is necessary (beyond status)
If a CGI script is uploaded from a UNIX client to a Windows server, the Windows server will change \n to \r\n at the end of every line; if that same script is then transferred to a UNIX server, the \r will be interpreted as part of the content, and NOT as end of line markers. These often show up as '^M' in error messages, or in emacs. You can fix this by filtering the file through tr -d '\r'.
Sample CGI script, which illustrates the data provided for either GET or POST requests:
A CGI script for a calculator, which generates HTML; note the translation of escaped characters back into their original form for input into BASH:#!/bin/sh echo Content-type: text/plain echo echo Server name is "$SERVER_NAME" echo Server is listening on port "$SERVER_PORT" echo Request method was "$REQUEST_METHOD" echo Query string is "$QUERY_STRING" echo Client IP address is "$REMOTE_ADDR" echo Content type is "$CONTENT_TYPE" echo Content length is "$CONTENT_LENGTH" echo Client will accept the MIME types "$HTTP_ACCEPT" echo Client Browser is "$HTTP_USER_AGENT" echo echo stdin follows: read l while [ -n "$l" ]; do echo $l read l done echo end of stdin echo
#!/bin/sh echo Content-type: text/html echo echo '<html>' echo '<body bgcolor="#E0FFFF">' echo '<h3>' echo "Hi $REMOTE_ADDR, welcome to the calculator at $SERVER_NAME!" echo '</h3><p>' echo '<h2>' if [ $REQUEST_METHOD = GET ]; then text=$(echo $QUERY_STRING | sed -e 's/^.*text=//') else read l text=$(echo $l | sed -e 's/^.*text=//') fi trtext=$(echo $text | sed -e 's/%2B/+/g' | sed -e 's^%2F^/^g' | sed -e 's/%26/\&/g' | sed -e 's/%7C/|/g' | sed -e 's/%21/!/g' | sed -e 's/%7E/~/g' | sed -e 's/%5E/^/g' | sed -e 's/%28/(/g' | sed -e 's^%29^)^g' | sed -e 's/%25/%/g' | sed -e 's/%3C/</g' | sed -e 's/%3E/>/g') result=$(echo $[$trtext]) if [ $? -ne 0 ]; then echo "Syntax error in expression $trtext" else echo "$trtext = $result" fi echo '</h2>' echo '</body>' echo '</html>' echo
was created using this code:
<form action="http://linux265.rwc.uc.edu/cgi-bin/get.cgi" method="GET"> <input type="checkbox" name="a_checkbox" value="on">A checkbox named "a_checkbox" <p> text: <input type=text size=25 value="" name=text> <input type="submit" value="Send"> </form>
was created using this code:
<form action="http://linux265.rwc.uc.edu/cgi-bin/post.cgi" method="POST"> <input type="checkbox" name="a_checkbox" value="on">A checkbox named "a_checkbox" <p> text: <input type=text size=25 value="" name=text> <input type="submit" value="Send"> </form>
The access_log file contains the following information for every file served to a client:
Then turn off FollowSymLinks and Indexes for all directories. This is a non-trivial exercise because on our systems, /srv is a symbolic link! (Hint: try using its real name.)
In practice, this needs to be done for the largest request that can be made of your server. This will be determined by both the longest possible URL and the largest possible query.Suppose that length is 700 bytes. Subtracting the length of the ethernet header, a firewall rule to drop excessive packets would look like this:
iptables -A INPUT -i eth0 -p tcp --dport 80 -m length --length 687:65535 -j DROPImplement such a firewall rule and test it, first sending a legitimate request, and then increasing the size of the request by manually typing additional query string characters on the end of the original query string. Use iptables -L -v to examine the dropped packet and bytes counts associated with your request.
What are the logistical difficulties in implementing such a rule on an enterprise server?
©2012, Kenneth R. Koehler. All Rights Reserved. This document may be freely reproduced provided that this copyright notice is included.
Please send comments or suggestions to the author.