Thursday, May 27, 2010

Apache Web Server "how to"

When you decide to setup a web server you will find that Apache is one of the most widely used servers on the Internet. It serves the majority of the web because it is powerful and flexible, being able to accommodate many different configurations. it is also open source so the code can be changed or modified without contacting the authors for a "hot fix."
Lets take a look at a sample Apache webserver. It will server up your pages from the document root. We are going to also install some security modules like mod_evasive and mod_security to protect our server from the Internet hordes.
We are going to build is a web cluster front end using Apache v2.2.


Looking at the httpd.conf

Below you will find the link to the Apache server example config file and below that is the same httpd.conf file in a text box. Both formats are available to make it easier for you to review the code. This example is a fully working config file with the exception of setting up a few variables for your environment. The config file is fully commented.
You can download the http.conf here by doing a "save as" or just clicking on the link and choosing download. Before using the config file take a look it below or download it and look at the options.

apache server httpd config file


#######################################################
###  Calomel.org  server httpd.conf   BEGIN
#######################################################
#
# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
#
# Do not add a slash at the end of the directory path.  If you point
# ServerRoot at a non-local disk, be sure to point the LockFile directive
# at a local disk.  If you wish to share the same ServerRoot for multiple
# httpd daemons, you will need to change at least LockFile and PidFile.
#
ServerRoot "/usr/local/apache2"

#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the 
# directive.
#
# Change this to Listen on specific IP addresses as shown below to 
# prevent Apache from glomming onto all bound IP addresses.
#
Listen 80

#
# Dynamic Shared Object (DSO) Support
#
# To be able to use the functionality of a module which was built as a DSO you
# have to place corresponding `LoadModule' lines at this location so the
# directives contained in it are actually available _before_ they are used.
# Statically compiled modules (those listed by `httpd -l') do not need
# to be loaded here.
#
LoadFile /usr/lib/libxml2.so
LoadModule evasive20_module modules/mod_evasive20.so
LoadModule security2_module modules/mod_security2.so
#


#
# If you wish httpd to run as a different user or group, you must run
# httpd as root initially and it will switch.  
#
# User/Group: The name (or #number) of the user/group to run httpd as.
# It is usually good practice to create a dedicated user and group for
# running httpd, as with most system services.
#
User web_daemon
Group web_daemon

# 'Main' server configuration
#
# The directives in this section set up the values used by the 'main'
# server, which responds to any requests that aren't handled by a
#  definition.  These values also provide defaults for
# any  containers you may define later in the file.
#
# All of these directives may appear inside  containers,
# in which case these default settings will be overridden for the
# virtual host being defined.
#
# ServerAdmin: Your address, where problems with the server should be
# e-mailed.  This address appears on some server-generated pages, such
# as error documents.  e.g. admin@your-domain.com
#
ServerAdmin webmaster@your_hostname.com

#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
#
ServerName your_hostname.com:80

# Timeout: The number of seconds before the daemon receives a request, does not
# get an answer and sends time out.
Timeout 180

##################################################################
#
# Client to server request limitations
LimitRequestBody 102400
LimitRequestFields 40
LimitRequestFieldsize 1000
LimitRequestLine 1000

##################################################################
#
# Mod_Rewrite limits on acceptable characters
RewriteEngine on
RewriteLog /usr/local/apache2/logs/mod_rewrite.log
RewriteLogLevel 0
RewriteRule [^a-zA-Z0-9|\.|/|_|-]  -  [F]
 
##################################################################
#
# Mod_evasive to avoid DDOS
DOSWhitelist 10.10.10.2
DOSLogDir "/usr/local/apache2/logs/mod_evasive.log"

    DOSHashTableSize    314739
    DOSPageCount        2
    DOSPageInterval     1
    DOSSiteCount        30
    DOSSiteInterval     1
    DOSBlockingPeriod   30

##################################################################
#
# Mod_Security settings
Include conf/modsecurity/*.conf
SecAuditLog /usr/local/apache2/logs/modsec_security.log
SecServerSignature your_hostname.com

##################################################################
#
# Mod_Expires to tell clients to cache files 
ExpiresActive On
ExpiresDefault "access plus 2 hours"

##################################################################

#
# EnableMMAP and EnableSendfile: On systems that support it, 
# memory-mapping or the sendfile syscall is used to deliver
# files.  This usually improves server performance, but must
# be turned off when serving from networked-mounted 
# filesystems or if support for these functions is otherwise
# broken on your system.
#
EnableMMAP on
EnableSendfile on

#
# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a 
# container, error messages relating to that virtual host will be
# logged here.  If you *do* define an error logfile for a 
# container, that host's errors will be logged there and not here.
#
ErrorLog logs/error_log
## Send the error logs to a remote log server
#ErrorLog syslog:local6

#
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
#
#LogLevel debug
LogLevel notice


    #
    # The following directives define some format nicknames for use with
    # a CustomLog directive (see below).
    #
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    
      # You need to enable mod_logio.c to use %I and %O
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    

    #
    # The location and format of the access logfile (Common Logfile Format).
    # If you do not define any access logfiles within a 
    # container, they will be logged here.  Contrariwise, if you *do*
    # define per- access logfiles, transactions will be
    # logged therein and *not* in this file.
    #
    CustomLog logs/access_log combined
    ## Send the access logs to a remote log server
    #CustomLog "|/usr/bin/logger -p local6.info" combined

    #
    # If you prefer a logfile with access, agent, and referer information
    # (Combined Logfile Format) you can use the following directive.
    #
    #CustomLog logs/access_log combined

#
# Customizable error responses come in three flavors:
# 1) plain text 2) local redirects 3) external redirects
# NOTE: using streight text is small and efficient.
#
ErrorDocument 505 "your_custom_error_message_here"
ErrorDocument 504 "your_custom_error_message_here"
ErrorDocument 503 "your_custom_error_message_here"
ErrorDocument 502 "your_custom_error_message_here"
ErrorDocument 501 "your_custom_error_message_here"
ErrorDocument 500 "your_custom_error_message_here"
ErrorDocument 417 "your_custom_error_message_here"
ErrorDocument 416 "your_custom_error_message_here"
ErrorDocument 415 "your_custom_error_message_here"
ErrorDocument 414 "your_custom_error_message_here"
ErrorDocument 413 "your_custom_error_message_here"
ErrorDocument 412 "your_custom_error_message_here"
ErrorDocument 411 "your_custom_error_message_here"
ErrorDocument 410 "your_custom_error_message_here"
ErrorDocument 409 "your_custom_error_message_here"
ErrorDocument 408 "your_custom_error_message_here"
ErrorDocument 407 "your_custom_error_message_here"
ErrorDocument 406 "your_custom_error_message_here"
ErrorDocument 405 "your_custom_error_message_here"
ErrorDocument 404 "your_custom_error_message_here"
ErrorDocument 403 "your_custom_error_message_here"
ErrorDocument 402 "your_custom_error_message_here"
ErrorDocument 401 "your_custom_error_message_here"
ErrorDocument 400 "your_custom_error_message_here"
#
## Other example error pages
#ErrorDocument 500 "The server has made a mistake."
#ErrorDocument 404 /missing.html
#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
#ErrorDocument 402 http://www.example.com/subscription_info.html
#
#######################################################
###  Calomel.org server  httpd.conf   END
#######################################################


Building the binaries

First, we need to install the following packages from source: Apache 2.2 or higher, mod_security, and mod_evasive. We will be building from source because we can setup exactly what we need and no more. There is no need for most of the packages or modules Apache comes with to be installed on our server. Let's keep it to a minimum.
The packages will be installed into the default directory /usr/local/apache2/ . The config files are in /usr/local/apache2/conf and the logs are in /usr/local/apache2/logs .
To build Apache 2.2 from source make a working directory any where you want and download the source to that directory. Untar the package and change to the untared directory. Execute the following line to make Apache with the modules we need for the server. The install will be put into /usr/local/apache2/
This line will:
  • Kill the running httpd deamon
  • Remove the /usr/local/apache2/bin to make room for the new build.
  • Clean the build dir and then configure
    • Disable cgi: cgi is not used on this machine.
    • Disable negotiation: Content negotiation, or more accurately content selection is not used.
    • Disable autoindex: do not list out directory contents if the index.html does not exist.
    • Disable status: we do not need the server status page on this server.
    • Disable userdir: sets the real directory in a user's home directory which is not on this server.
    • Enable rewrite: to rewrite specified urls like home directories and error pages.
    • Enable unique-id:
    • Enable expires: for cache control and to save server bandwidth.
  • Make the binaries and install them into /usr/local/apache2/bin/ with make install.
killall httpd;rm -rf /usr/local/apache2/bin;make clean; ./configure --disable-cgi --disable-negotiation --disable-autoindex --disable-status --disable-userdir --enable-rewrite --enable-unique-id --enable-expires && make && make install
For security and to reduce the change that a DDOS will affect our new server we are going to also install a the modules mod_evasive and mod_security.
To build mod_evasive download the latest source code here and put it into the working directory. Untar the package and execute the following line to build it. Copy the mod_evasive20.so file to the apache2 modules directory /usr/local/apache2/modules/
/usr/local/apache2/bin/apxs -i -a -c mod_evasive20.c
To build mod_security download the latest source code here and put it into the working directory. Untar the package and execute the following line to build it. Copy the mod_security2.so file to the apache2 modules directory /usr/local/apache2/modules/
make && make install



Need help setting up an Apache reverse proxy in front of a cluster? Make sure to check out the Apache Cluster Reverse Proxy.


Editing the httpd.conf

Now that the install is finished and the security modules are built and copied to the correct directory, it is time to download the config file httpd.conf from above. Save the calomel.org httpd.conf file to /usr/local/apache2/conf/httpd.conf . It is time to take a look at some of the directives that need your attention.
The "user" and "group" need to be a valid non-privileged user. You may want to avoid using generic system users like "nobody" "or daemon" and make your own user. For the example we used "web_daemon".
Check the ServerName and ServerAdmin directives to make sure they reflect the name of your server and the contact information in case someone has any problems.
The settings for Mod_evasive are to avoid DDOS attacks. The directive DOSWhitelist can be a single ip or network you wish to exclude like a local LAN from the evasive limitations.
The Mod_Security settings set the directory where the default security rules can be found and you need to make sure the directive SecServerSignature is set to your hostname.
Mod_Expires to tell clients to cache files so you can save bandwidth. If a client is going from one page to another on your site. You can ask them to keep a cached copy of objects like pictures and buttons so they do not download the same data over and over again.
Customizable error responses allow you to customize how a remote client is treated when they encounter an error. Here you can specify a 1) plain text, 2) local redirects or 3) external redirects to help error-ed clients find your content. In the example we set all errors to the simple text string "your_custom_error_message_here".



Want more speed? Make sure to also check out the Network Speed and Performance Guide. With a little time and understanding you could easily double your firewall's throughput.


Starting the server

The last step is to make sure the server will start without error. The following will start, stop or do a graceful restart of the apache server:
/usr/local/apache2/bin/apachectl -k start
/usr/local/apache2/bin/apachectl -k stop
/usr/local/apache2/bin/apachectl -k graceful
If you get an error make sure to check the access_log and error_log in the /usr/local/apache2/log/ directory. All of the modules that we built will also log to the same directory.


SECURITY NOTE: We highly recommend using a reverse proxy like Pound to front end your web servers. Pound offers an added layer of security and can be used to filter most malicious requests from ever hitting the web server. Use Pound to stop the bad bots and allow your web server to focus on good clients. For a complete explanation and examples check out the Calomel.org Pound reverse proxy "how to".

No comments: