Understanding Apache 2.0 and Tomcat 4.1 Configuration for Linux and NetWare®

Brad Nicholes, Senior Software Engineer,

Member, Apache Software Foundation, Novell Inc.

Mark Tyler

Senior Software Engineer, Novell Inc.

Jean-Jacques Clar

Senior Software Engineer, Novell Inc.

Agenda

Apache Configuration

Apache 2.0 Status

Multi-Processing Modules

General Configuration

Securing the Web Server with Mod_Auth_LDAP

Tomcat Configuration

Tomcat 4.1 Overview

Configuration for NetWare and Linux

Connecting Apache to Tomcat with Mod_JK

Web Server Performance

Monitoring and Measuring Tools

Mod_Cache Configuration

Directives

Compression

Apache 2.0 Status

Shipping:

NetWare 6.5 SP3/OES	-Apache 2.0.52

SUSE LINUX OES	-Apache 2.0.49

Development Stable:

Apache 2.0.54-dev

Development Unstable:

Apache 2.1.4-dev

No Known Vulnerabilities

Apache 2.0 on NetWare OES

Ships by default with NetWare OES

Two instances of Apache

Web based administration server running on port 2200

Specialized configuration

Configuration is stored in SYS:\adminsrv

Running in protected address space

DO NOT ALTER!

General purpose web server

Configured through the standard HTTPD.conf file

Running in OS address space

Customize to your needs

Apache 2.0 on SuSE Linux OES

Installed by default with Open Enterprise Server

May not be the latest version but has been patched with critical updates

Fully configured for SSL on port 443

Mod_JK Tomcat connector configured

No administration server running on port 2200

Administration is handle through YaST

Base configuration files are located in /etc/apache2

Apache 2.0 on SuSE Linux OES

File Locations

Modules - /usr/lib/apache2

Configuration - /etc/apache2

Logs - /var/log/apache2

Cgi-bin - /srv/www/cgi-bin

DocumentRoot - /srv/www/htdocs

Binary - /usr/sbin/httpd2 (symlink to actual binary)

/usr/sbin/httpd2-worker

/usr/sbin/httpd2-prefork

Other support binaries - /usr/sbin

Startup script – /usr/sbin/rcapache2

Symlink to /etc/init.d/apache2

Multi-Processing Modules

Accommodate a wide variety of operating environments on different platforms

Responsible for:

Binding to network ports

Accepting requests

Dispatching worker threads to handle requests

Allows customization for particular sites

Scalability in a threaded environment – Worker MPM

Compatibility with older modules – Prefork MPM

Platform custom – NetWare MPM, WinNT MPM

NetWare MPM

One parent thread, many worker threads

Each thread is a light weight process

NetWare

Thread

NetWare

Thread

NetWare

Thread

Master

Server

Multi-Processing Modules

NetWare MPM

StartThreads - Number of worker threads launched at server startup

MinSpareThreads - Minimum number of idle threads allowed before additional worker threads are created

MaxSpareThreads - Maximum number of idle threads allowed before excess worker threads are destroyed

MaxThreads - Maximum number of worker threads allowed

MaxMemFree - Maximum amount of memory that the main allocator is allowed to hold without calling free()

http://httpd.apache.org/docs-2.0/mod/mpm_netware.html

Worker MPM

Combines multi-process and multi-threaded models

Variable number of processes (parents)

Fixed number of threads

Each child process handles many concurrent connections

Stability of multiple processes

Performance of multiple threads

Reduces the memory footprint

Child

Child

Child

Thread

Thread

Thread

Master

Server

(Parent)

Multi-Processing Modules

Worker MPM - Multi-Processing Module implementing a hybrid multi-threaded / multi-process web server

StartServers - Number of child server processes created at startup

MinSpareThreads - Minimum number of idle threads allowed before additional worker threads are created

MaxSpareThreads - Maximum number of idle threads allowed before excess worker threads are destroyed

MaxClients - Maximum number of worker threads allowed

MaxMemFree - Maximum amount of memory that the main allocator is allowed to hold without calling free()

ThreadsPerChild - Number of threads created by each child process

http://httpd.apache.org/docs-2.0/mod/worker.htm

Prefork MPM

Stable but slower (based on documentation)

One parent (master server)

many children (workers)

Each child server is a process itself

Each child handles one connection at a time

Uses more memory

Similar to the NetWare MPM but using processes instead of threads

Child

Child

Child

Master

Server

(Parent)

Multi-Processing Modules

Prefork MPM - Implements a non-threaded, pre-forking web server

StartServers - Number of child server processes created at startup

MinSpareServers - Minimum number of idle child server processes

MaxSpareServers - Maximum number of idle child server processes

MaxClients - Maximum number of child processes that will be created to serve requests

MaxMemFree - Maximum amount of memory that the main allocator is allowed to hold without calling free()

http://httpd.apache.org/docs-2.0/mod/prefork.html

Reading the Documentation

Online: http://httpd.apache.org/docs-2.0/

Also installed with every instance of Apache

Most directives consist of a name and a single value

Some directives may have multiple, optional or boolean values

Example directive:

Configuration File Syntax

The default HTTPD.conf file contains a very good explanation of each directive that is used and why

The directives are not ordered

The configuration file contains one directive per line but the “\” may be used to indicate that the directive continues to the next line

Configuration directives are case-insensitive but some arguments may be case-sensitive

Lines that begin with “#” are considered to be comments

<IfDefine> can be used to block out sections of the configuration file that are only used if a specific environment variable has been defined

HTTPD.conf Highlights

ServerRoot – Base directory for the server installation

All relative paths are derived from the ServerRoot

If you have multiple installations of the web server, make sure that the ServerRoot points to the respective install locations

PidFile (Non-NetWare) - File where the server records the process ID of the daemon

If an error message occurs when starting Apache on Linux indicating that HTTPD is already running, it may be that an old httpd.pid file was orphaned after an abnormal shutdown (ie. Kill -9)

HTTPD.conf Highlights

Timeout – Amount of time the server will wait for send or receive events before failing a request (Default 300 seconds or 5 minutes)

If Apache appears to hang during a shutting down on NetWare, it may be that a worker thread is waiting for data from the client. After the timeout period has expired, Apache will shutdown normally.

KeepAlive – Enable persistent connections (ie. Avoids having to reconnect with the same client on sub-requests)

If the connection is not properly terminated by the client, the connection will be held for the duration of the KeepAliveTimeout value. This could cause unecessary latency when responding to new requests on a busy server

HTTPD.conf Highlights

Listen – Binds Apache to a specific IP address and/or port

If only a port is specified, Apache will listen to that port on all IP addresses assigned to the box

LoadModule – Loads an external Apache module

<IfModule> - Should surround module specific directives to prevent invalid configuration if a module has not been loaded

UseCanonicalName – Determines how Apache constructs self-referencing URLs (ie. Redirects)

ServerName – Used to construct a self-referencing URL when UseCanonicalName is set to ON. Otherwise Apache uses the host name supplied by the client

HTTPD.conf Highlights

DocumentRoot – Default location from which all documents are served

If an alias for a URI is not found, Apache will attempt to serve the page from the DocumentRoot

Options – Configures the features that are available in a specific directory

Indexes – Allows a directory listing

AddIcon - Specifies the location and file name of the icon that should be displayed for a given file type

Multiviews – Allows language negotiation

ExecCGI – Allow CGI binaries or scripts to be executed

Includes – Enables Server-Side includes or parsed HTML

HTTPD.conf Highlights

Order/Allow/Deny – Specifies access control restrictions

The Order directive determines whether Apache should be inclusive or exclusive when applying access control

Both Allow and Deny can be used to restrict access based on full or partial IP addresses, network masks or environment variables

DirectoryIndex – Specifies the default file name(s) to serve when no page is specifed in the request

The file index.html.var can be used to specify additional language negotiation rules rather than an actual web page

HTTPD.conf Highlights

CustomLog – Defines the location and format of a custom log file

When used with the LogFormat directive, the contents of the log file as well as the format can be specified

Multiple log files can be defined containing different information or layouts (Warning: specifying additional log files may hurt performance)

Alias – Associates a URI prefix with a physical directory location

<Directory>/<Location>/<Files> - Should accompany the Alias directive to indicate how files are accessed from the aliased location

HTTPD.conf Highlights

ErrorDocument – Defines a custom or user friendly response to an HTTP error

The response can be in plain text, local redirect or external redirect

If the response is a redirect, the language can be negotiated so that it is appropriate for the request

BrowserMatch – Customizes the request handling for particular browsers

Can be used to force a response to HTTP 1.0 rather than 1.1 or to turn off keepalive connections for older browsers

Modularizing the Configuration

Functional blocks of directives can be put into a separate configuration file

Use the “Include” directive to instruct Apache to read additional configuration files

If the “Include” directive specifies a directory, all files within the directory will be read as additional configuration files

Wildcards can be used to specify a certain set of additional configuration files (include conf/*.conf)

Virtual Hosts

Apache supports two types of virtual hosts

Name-based virtual host

Selects a virtual host configuration based on the domain name of the request

Allows more that one virtual host per IP address

IP-based virtual

Selects a virtual host configuration based on the IP address of the request

Each IP address belongs to a specific virtual host

Each virtual host can be configured independently

ServerName, DocumentRoot, Aliases, log files, etc.

Name-Based Virtual Host

NameVirtualHost *:80
<VirtualHost *:80>
ServerName www.domain.com
ServerAlias domain.com *.domain.com
DocumentRoot /www/domain
</VirtualHost>
<VirtualHost *:80>
ServerName www.otherdomain.com
DocumentRoot /www/otherdomain
</VirtualHost>

NameVirtualHost specifies the IP address that will be shared

ServerAlias directive allows access to a specific virtual host by different domain names

Apache uses the ServerName directive to decide which virtual host configuration applies

IP-Based Virtual Host

<VirtualHost www.smallco.com>
ServerAdmin webmaster@mail.smallco.com
DocumentRoot /groups/smallco/www
ServerName www.smallco.com
ErrorLog /groups/smallco/logs/error_log
TransferLog /groups/smallco/logs/access_log
</VirtualHost>
<VirtualHost www.baygroup.org>
ServerAdmin webmaster@mail.baygroup.org
DocumentRoot /groups/baygroup/www
ServerName www.baygroup.org
ErrorLog /groups/baygroup/logs/error_log
TransferLog /groups/baygroup/logs/access_log
</VirtualHost>

Apache determines which virtual host to use based off of the IP address

Almost any configuration directive can be put in a virtual host block with the exception of some of the process creation directives

What is Mod_Auth_LDAP

Authentication module that allows Apache to authenticate a user against an LDAP compliant directory

Allows for complex authentication and authorization policies rather than just user ID and password

Can be used to extract additional LDAP object attributes that can be referenced by downstream CGI modules or scripts

Directives – Mod_Auth_LDAP

AuthLDAPRemoteUserIsDN

Use the DN of the user name to set the REMOTE_USER environment variable

AuthLDAPCompareDNOnServer

Use the LDAP server to compare the DNs

AuthLDAPUrl

URL specifying the LDAP search parameters

AuthLDAPDereferenceAliases

Specifies when the module will de-reference aliases

AuthLDAPGroupAttributeIsDN

Use the DN of the user name when checking for group membership

AuthLDAPCharsetConfig

Language to charset conversion file

AuthLDAPGroupAttribute

Specifies which LDAP attributes will be used to check for group membership

AuthLDAPBindPassword

Password used in conjunction with the bind DN

AuthLDAPFrontPageHack

Allow LDAP authentication to work with MS FrontPage

AuthLDAPBindDN

Optional DN to use when binding to the LDAP server

AuthLDAPEnabled

Turn on or off LDAP authentication

AuthLDAPAuthoritative

Prevent other authentication modules from authenticating the user if LDAP authentication fails

<Directory /www/docs>

Order deny,allow

Allow from all

AuthType Basic

AuthName Secure_Alias_Test

AuthLDAPURL ldap://ldap-server/o=ctx?cn?sub

require valid-user

</Directory>

Directive Usage

Search for the user based on the specified attribute and through all sub-contexts

<Directory /www/docs>

Order deny,allow

Allow from all

AuthType Basic

AuthName Secure_Alias_Test

AuthLDAPBindDN cn=ldapuser,o=ctx

AuthLDAPBindPassword mY_SecrEt

AuthLDAPURL ldap://ldap-server/o=ctx

require valid-user

</Directory>

Directive Usage

Bind to the LDAP server for all operations using a specific user ID and password

LDAP URL

The LDAP Url syntax is defined by RFC 2255

The Url format is:	scheme://host:port/basedn?attributes?scope?filter

Scheme – “ldap://” for regular or unsecured ldap connections or “ldaps://” for secured connections

Host:port – name/port of the ldap server. Multiple hosts can be specified (port defaults 389 for ldap:// or 636 for ldaps://)

Basedn – base DN of the branch of the directory where the searches should begin

Attributes – attribute to search for. If multiple attributes are listed, separated by a comma, only the first will be used (default “uid”)

Scope – can be either “one” or “sub” meaning search within a single context or search all sub contexts (default “sub”)

Filter – LDAP search filter (default “objectClass=*”)

LDAP Url Examples

Allow access to anyone who exists in the LDAP directory

ldap://ldap1.airius.com/ou=People,o=Airius

Note: above example assumes defaults

Port: 389

Attribute: uid

Scope: sub

Filter: (objectClass=*)

Use redundant LDAP servers

“ldap://ldap1.airius.com ldap2.airius.com/ou=People,o=Airius”

Note: Since the host names are separated by a space, this Url must be surrounded by double-quotes when used in the AuthLDAPUrl directive

LDAP Url Examples

Allow access to all users whose sn attribute does not start with “jo”

ldap://ldap.airius.com/ou=People,o=Airius?cn?sub?(!(sn=jo*))

Note: The search is based on cn rather than the default uid attribute

Extract additional attributes from the authenticated user object

ldap://ldap.airius.com/ou=People,o=Airius?cn,sn,email,phone

Note: The value of each attribute will be added to the environment as AUTHENTICATE_<ATTR-NAME>

Note: the listed attributes might not be public. The directives AuthLDAPBindDN and AuthLDAPBindPassword may be necessary to allow Mod_Auth_LDAP access to the LDAP directory

LDAP Filters

Defines which entries within a scope to retrieve and send back to the requesting application

Search filters are written as an ABNF formatted string

Search filter syntax is described in RFC 2254

The default filter if none is specified in the LDAP URL is (objectClass=*)

Filter grammar operators include

=	(Equality and presence matching)

<= or >= (Greater-than or Less-than matching)

~=	(Approximate matching)

&, |, !	(Boolean operators)

LDAP Filter Examples

(objectClass=*)

Allow all objects to be searched

(&(objectClass=inetOrgPerson)(telephoneNumber=*))

Return all “inetOrgPerson” objects which have a “telephoneNumber” attribute

(&(cn=mary*)(!(sn=jones)))

Find all objects whose cn attribute begins with the value “mary” except for those objects whose sn attribute is equal to “jones”

Authorization: Not Just a “Valid-User”

The “Require” directive can be used to grant authorization in several different ways

Valid-user – authorizes any user with valid LDAP credentials

User – specifies which users names are allowed access by performing an LDAP compare operation

Group – specifies an LDAP group whose members are allowed access

DN – allows access based on fully distinguished names

Authorization: Require User

Require User – Allows multiple users

Specify multiple users by listing each user name separated by a space

If the user name contains a space then it must be enclosed by double-quotes and the directive can not list more than one

Multiple users can be specified through multiple “Require User” directives

Authorization: Require Group

Require Group – use a fully distinguished name

Do not surround the group name with quotes

Behavior of this directive can be modified with:

AuthLDAPGroupAttribute

Specifies additional attributes used to check for group membership

Default attributes are “member” and “uniqueMember”

AuthLDAPGroupAttributeIsDN

Set to “ON” means use the fully distinguished name of the user when checking membership

Default is “ON”

Authorization: Require DN

Require DN – use a fully distinguished user name

Compares the distinguished name retrieved from the directory against the specified name

The behavior of this directive can be modified with

AuthLDAPCompareDNOnServer

If set to “ON”, mod_auth_LDAP will search the directory for the specified DN and then compare it with the user DN retrieved during the authentication phase

Otherwise mod_auth_LDAP does a simple string comparison

What is Util_LDAP (aka. Mod_LDAP)

Provides common services for LDAP based modules

Primary purpose is to enhance the performance of LDAP connections and operations

Provides LDAP connection pools

Provides LDAP credential and operations caching

Supports SSL connections between the web server and the LDAP server

Dependant on LDAP support through apr-util

Directives – Util_LDAP

LDAPTrustedCAType

Specifies the type of the Certificate Authority file

LDAPOpCacheTTL

Maximum time that cached entries in the operations cache remain valid

LDAPTrustedCA

Specifies the file containing the trusted Certificate Authority or certificate database

LDAPOpCacheEntries

Maximum number of entries allowed in the LDAP compare operations cache

LDAPSharedCacheSize

Size in bytes of the shared-memory cache

LDAPCacheTTL

Maximum time that cached items remain valid

LDAPSharedCacheFile

Specifies the shared memory cache file

LDAPCacheEntries

Maximum number of entries allowed in the primary LDAP cache

Enabling SSL/TLS

LDAPTrustedCA /etc/ssl/server/certs/ldapcert.pem

LDAPTrustedCAType BASE64_FILE

<Directory /www/docs>

Order deny,allow

Allow from all

AuthType Basic

AuthName Secure_Alias_Test

AuthLDAPURL ldaps://ldap-server:636/o=ctx

require valid-user

</Directory>

Specify “ldaps://” rather than “ldap://” to establish an SSL connection

Can also specify the port along with the host

Enabling SSL/TLS

The ability to establish an SSL connection to the LDAP server is supported by OpenLDAP, Novell LDAP, Microsoft and iPlanet SDK’s

Each LDAP SDK implements SSL connection APIs differently

OpenLDAP

Only supports BASE64_FILE type certificates

Novell LDAP

Support BASE64_FILE and DER_FILE type certificates

iPlanet

Only supports CERT7_DB_FILE type certificates

LDAPTrustedCA must specify a cert7_db file

Microsoft

Uses registry certificate store and is always assumed to be available

LDAP Credential and Operation Caching

One credential cache and two types of operation caches are maintained for each LDAP URL specified in the configuration

LDAP Credential Cache

Caches the user name, full DN, password and the amount of time the entry has been cached

If the user name and password match and the entry has not expired, the search/bind phase is by-passed

Failed binds are not cached

LDAP Operations Cache

Group membership cache and a DN comparison cache

Util_LDAP Cache Status Display

Implements a cache data display so that the different types of caches can be monitored

Monitored attributes:

Number of entries within each cache

Number of successful hits vs accesses (fetches)

Number of inserts vs deletes

If and when a purge on the cache has been done

Each individual cache displays its own specific information

Enabled by setting the “ldap-status” handler

Cache Overview Display

Search Cache Display

Mod_Authnz_LDAP for Apache 2.1/2.2

No longer an experimental module

LoadModule requirements:

Mod_auth_basic – Basic authentication (required)

Util_ldap – LDAP common operations (required)

Mod_authnz_ldap – LDAP authentication and authorization (required)

Require ldap-user – replaces “Require user”

Require ldap-group – replaces “Require group”

Require ldap-dn – replaces “Require dn”

Require ldap-attribute - NEW

Require ldap-filter - NEW

Mod_authz_user – User authorization (optional)

Require valid-user

Require user

Mod_authz_group – Group authorization (optional)

Require group

Tomcat Configuration

Agenda

Tomcat Configuration

Tomcat 4.1 Overview

Configuration for NetWare and Linux

Connecting Apache to Tomcat with Mod_JK

Tomcat 4.1 Overview

What is Tomcat?

Servlet container for processing Java Servlets and JavaServer Pages (JSPs).

iManager is an example of a web application which relies on Tomcat.

One of many open source Java subprojects developed by members of the Jakarta Project.

The Jakarta Project is part of the Apache Software Foundation (ASF).

Code-named Catalina

Official Tomcat Site

http://jakarta.apache.org/tomcat

Tomcat 4.1 Background

Why use Tomcat 4.1 when Tomcat 5.0 is available?

The iManager web application contains pre-compiled code designed for Tomcat 4.1.

This pre-compiled code is not compatible with Tomcat 5.0.

Look for Tomcat 5.0 compatibility soon.

Tomcat 5.0

Netware

Not installed by default

$CATALINA_HOME = sys:/tomcat/5

Linux

Ships with SLES 9

$CATALINA_HOME = /usr/share/tomcat

Config files are in /etc/tomcat/base

Log files are in /var/log/tomcat

Tomcat 4.1 on NetWare and Linux

Tomcat on Novell's Open Enterprise Server (OES)

NetWare 6.5

$CATALINA_HOME = sys:/tomcat/4

SUSE LINUX Enterprise Server (SLES) 9

$CATALINA_HOME = /var/opt/novell/tomcat4

Tomcat 4.1 Directories

$CATALINA_HOME/

bin/ Binary executables and scripts

common/ Classes available to both Catalina internal classes and web applications

conf/ Configuration files

logs/ Destination directory for log files

server/ Internal Catalina classes and their dependencies

shared/ Classes shared by all web applications

temp/ Directory for JVM temporary files

webapps/ Base directory containing web applications included with Tomcat 4.1

work/ Scratch directory used by Tomcat for holding temporary files and directories

Tomcat Scripts

Netware	Linux

Start	tomcat4	rcnovell-tomcat4 start

Stop	tc4stop	rcnovell-tomcat4 stop

Check if Tomcat is running on Netware

java -show

Logger Screen

System Console

Check if Tomcat is running on Linux

ps aux | grep java

Server.xml

Where?

$CATALINA_HOME/conf/server.xml

What?

Tomcat's main configuration file

Elements include:

Top level elements (e.g. <Server>)

Connectors (e.g. <Coyote JK 2>)

Containers (e.g. <Context>)

Nested Components (e.g. <Realm>)

Server.xml Changes

The server.xml installed with OES is very similar to Jakarta's default with the following modifications:

AJP port change from 8009 to 9009/9010

Use “JNDIRealm” for authentication/authorization instead of “UserDatabaseRealm”

Commented out port 8080, the internal HTTP stack

Mod_jk Overview

Servlets

Module mod_JK

Apache Web Server

JSP

Tomcat Servlet Container

Web Browser

How is Mod_jk configured?

The following lines are included in Apache's httpd.conf:

LoadModule jk_module modules/mod_jk.nlm <IfModule mod_jk.c> JkWorkersFile “sys:/adminsrv/conf/mod_jk/workers.properties” JkLogFile “logs/mod_jk.log” JkLogLevel error </IfModule>

<IfModule !mod_jk.c> LoadModule jk_module /opt/novell/httpd/modules/mod_jk.so JkWorkersFile /etc/opt/novell/httpd/conf/workers.properties JkLogFile /var/opt/novell/httpd/logs/mod_jk.log JkLogLevel error </IfModule>

On Linux, httpd.conf indirectly includes these lines. http.conf includes default_server.conf which includes conf.d/*.conf which expands to include /etc/apache2/conf.d/020mod_jk.conf.

Workers.properties

workers.tomcat_home=sys:/tomcat/4 workers.java_home=sys:/java worker.ajp13.port=9010 worker.ajp13.host=127.0.0.1 worker.ajp13.type=ajp13 worker.ajp13.reply_timeout=180000 worker.ajp13.lbfactor=1 worker.ajp13.cachesize=250

workers.tomcat_home=/var/opt/novell/tomcat4 workers.java_home=/opt/novell/java worker.ajp13.port=9009 worker.ajp13.host=127.0.0.1 worker.ajp13.type=ajp13 worker.ajp13.lbfactor=1 worker.ajp13.cachesize=250

Server.xml

<!-- Define a Coyote/JK2 AJP 1.3 Connector on port 8009 --> <ConnectorclassName="org.apache.coyote.tomcat4.CoyoteConnector" port="9010" minProcessors="5" maxProcessors="75" enableLookups="true" acceptCount="10" debug="0" connectionTimeout="0" useURIValidationHack="false" protocolHandlerClassName="org.apache.jk.server.JkCoyoteHandler"/>

<!-- Define a Coyote/JK2 AJP 1.3 Connector on port 8009 --> <ConnectorclassName="org.apache.coyote.tomcat4.CoyoteConnector" port="9009" minProcessors="5" maxProcessors="75" enableLookups="true" acceptCount="10" debug="0" connectionTimeout="0" useURIValidationHack="false" protocolHandlerClassName="org.apache.jk.server.JkCoyoteHandler"/>

Web Performance

Agenda

Web Server Performance

Monitoring and Measuring Tools

Mod_Cache Configuration

Directives

Compression

Server scalability – Scaling-OUT

Scaling-out?

Multiple separate systems function as a single system:

Proxy and Load Balancing.

Browser

Internet

Web Server

Tomcat Server

Web Server

Proxy Server

Server scalability – Scaling-UP

Increasing capacity of subsystems:

Applications

Memory

Processor

Network

Disk

Server scalability – Scaling-UP

Optimal performance requires balance between subsystems

Could easily get out-of-balance

The weakest link will limit server performance

Monitoring - why?

Finding bottlenecks in your system

Finding The Hotspot

Knowing your system

Spotting unusual behaviors

Help predicts long term trends

Monitoring Tools – Novell Remote Manager (NRM)

NRM as a monitoring tool

Server Health

Log files

Subsystem status

Configuration changes

Sampling monitoring

Profiling

Health Statistics Graphs

Monitoring Tools – Linux

top

KDE System Guard

Xosview

Browse your system menu or add packages

Chapter in: Tuning IBM Servers for Performance

Covers Windows, Linux, and NetWare

http://publib-b.boulder.ibm.com/Redbooks.nsf/RedbookAbstracts/sg245287.html

available as a pdf file (free) or hardcopy.

Baseline

What to measure:

Throughput

Requests (transactions) per second (rps)

Bandwith (kb/sec)

Latency (msec)

How to measure:

WebBench

http://www.veritest.com/benchmarks/webbench/default.asp

WebStone

http://www.mindcraft.com/webstone/

ab

http://httpd.apache.org/docs-2.0/programs/ab.html

Using apache caching modules

http://httpd.apache.org/docs-2.0/mod/mod_cache.html

http://httpd.apache.org/docs-2.0/mod/mod_mem_cache.html

LoadModule cache_module modules/mod_cache.so
<IfModule mod_cache.c>
CacheMaxExpire 60000 (sec)
CacheIgnoreCacheControl Off
CacheDisable /some_directory
LoadModule mem_cache_module modules/mod_mem_cache.so
<IfModule mod_mem_cache.c>
CacheEnable mem /some_directory
MCacheSize 700000 (KBytes)
MCacheMaxObjectCount 9001
MCacheMinObjectSize 1 (Bytes)
MCacheMaxObjectSize 1024000 (Bytes)
MCacheMaxStreamingBuffer 800000 (Bytes)
</IfModule>
</IfModule>

Results from the performance lab...

Tuning parameters - Apache

logging

keep alive

KeepAlive on

MaxKeepAliveRequests

KeepAliveTimeOut

Timeout

AllowOverride

EnableSendFile

ExtendedStatus

Removing unused modules

last accessed time: atime

Using compression

Compressing specific extensions:

AddOutputFilterByType DEFLATE text/html text/plain text/xml

or excluding files extensions:

SetEnvIfNoCase Request_URI \

\.(?:gif|jpe?g|png)$ no-gzip dont-vary

Compression enabled

Question & Answer

Mod_auth_LDAP is an authentication module that allows Apache to authenticate a user against an LDAP compliant directory. One of the features of mod_auth_LDAP is its ability to take advantage of LDAP filters while searching for the specified user. These filters allow the module to target the results of the search in a much more efficient way rather than simply searching the entire directory or context. Another feature of the module is that it can be configured to extract additional attributes about the authenticated user. These attributes once extracted, are assigned to environment variables that can be used later by other Apache modules or downstream CGI modules and scripts.

There are a number of directives that are implemented by the Mod_Auth_LDAP module. The most notable are AuthLDAPURL, AuthLDAPBindDN and AuthLDAPBindPassword. These directives provide the module with the information that it needs to establish a connection to an LDAP server as well as log in if necessary.

A complete LDAP URL consists of several different types of information that is required to not only establish a connection to the LDAP server, but to also direct how and where the search will take place. The following list describes the different parts of the LDAP URL.

An RFC 2255 URL which specifies the LDAP search parameters to use. The syntax of the URL is

ldap://host:port/basedn?attribute?scope?filter

ldap

For regular ldap, use the string ldap. For secure LDAP, use ldaps instead. Secure LDAP is only available if Apache was linked to an LDAP library with SSL support.

host:port

The name/port of the ldap server (defaults to localhost:389 for ldap, and localhost:636 for ldaps). To specify multiple, redundant LDAP servers, just list all servers, separated by spaces. mod_auth_ldap will try connecting to each server in turn, until it makes a successful connection.

Once a connection has been made to a server, that connection remains active for the life of the httpd process, or until the LDAP server goes down.

If the LDAP server goes down and breaks an existing connection, mod_auth_ldap will attempt to re-connect, starting with the primary server, and trying each redundant server in turn. Note that this is different than a true round-robin search.

basedn

The DN of the branch of the directory where all searches should start from. At the very least, this must be the top of your directory tree, but could also specify a subtree in the directory.

attribute

The attribute to search for. Although RFC 2255 allows a comma-separated list of attributes, only the first attribute will be used, no matter how many are provided. If no attributes are provided, the default is to use uid. It's a good idea to choose an attribute that will be unique across all entries in the subtree you will be using.

scope

The scope of the search. Can be either one or sub. Note that a scope of base is also supported by RFC 2255, but is not supported by this module. If the scope is not provided, or if base scope is specified, the default is to use a scope of sub.

filter

A valid LDAP search filter. If not provided, defaults to (objectClass=*), which will search for all objects in the tree. Filters are limited to approximately 8000 characters (the definition of MAX_STRING_LEN in the Apache source code). This should be than sufficient for any application.

When doing searches, the attribute, filter and username passed by the HTTP client are combined to create a search filter that looks like (&(filter)(attribute=username)).

For example, consider an URL of ldap://ldap.airius.com/o=Airius?cn?sub?(posixid=*). When a client attempts to connect using a username of Babs Jenson, the resulting search filter will be (&(posixid=*)(cn=Babs Jenson)).

By default the connection to the LDAP server is through an anonymous bind. By binding anonymously, mod_auth_ldap is allowed to conduct searches based on public attributes only. In order to search the directory based on complex filters that may reference private attributes or to extract data from protected attributes, mod_auth_ldap must be allowed to bind to the server with a user ID and password that will allow it more access to the directory than does an anonymous bind. Binding with a valid user ID and password requires that the directives AuthLDAPBindDN and AuthLDAPBindPassword be used within the configuration.

An RFC 2255 URL which specifies the LDAP search parameters to use. The syntax of the URL is

ldap://host:port/basedn?attribute?scope?filter

ldap

For regular ldap, use the string ldap. For secure LDAP, use ldaps instead. Secure LDAP is only available if Apache was linked to an LDAP library with SSL support.

host:port

The name/port of the ldap server (defaults to localhost:389 for ldap, and localhost:636 for ldaps). To specify multiple, redundant LDAP servers, just list all servers, separated by spaces. mod_auth_ldap will try connecting to each server in turn, until it makes a successful connection.

Once a connection has been made to a server, that connection remains active for the life of the httpd process, or until the LDAP server goes down.

If the LDAP server goes down and breaks an existing connection, mod_auth_ldap will attempt to re-connect, starting with the primary server, and trying each redundant server in turn. Note that this is different than a true round-robin search.

basedn

The DN of the branch of the directory where all searches should start from. At the very least, this must be the top of your directory tree, but could also specify a subtree in the directory.

attribute

The attribute to search for. Although RFC 2255 allows a comma-separated list of attributes, only the first attribute will be used, no matter how many are provided. If no attributes are provided, the default is to use uid. It's a good idea to choose an attribute that will be unique across all entries in the subtree you will be using.

scope

The scope of the search. Can be either one or sub. Note that a scope of base is also supported by RFC 2255, but is not supported by this module. If the scope is not provided, or if base scope is specified, the default is to use a scope of sub.

filter

A valid LDAP search filter. If not provided, defaults to (objectClass=*), which will search for all objects in the tree. Filters are limited to approximately 8000 characters (the definition of MAX_STRING_LEN in the Apache source code). This should be than sufficient for any application.

In the first example of an LDAP URL, the LDAP connection will be established on the non-secure port 389 of the ldap1.airius.com host. All searches will be done within the ou=People,o=Airius context including all sub-contexts using the UID attribute of each matching object. The default filter (objectClass=*) will also be used meaning that the results of the search will include all objects. The LDAP URL allows you to configure multiple LDAP servers in-case Mod_Auth_LDAP is unable to establish a connection to the primary LDAP server. A special note to keep in mind is that since the LDAP host names must be separated by a space, whenever multiple hosts are specified, the LDAP URL must be surrounded by double quotes.

In this example the LDAP URL includes a search filter. This filter says that only objects whose ‘sn’ attribute does not start with the letters ‘jo’, will be searched. It also specifies that the search attribute will be the ‘cn’ attribute rather than the default ‘uid’. The second example specifies additional attributes whose values will be returned as part of the LDAP search. These attributes will be assigned to environment variables that begin with AUTHENTICATE_ + the actual attribute name. Once the values of the attributes have been assigned to the environment variables, this data can be extracted from the request_rec or retrieved through standard means by a downstream CGI application.

An LDAP filter defines which objects are eligible to be part of the LDAP search. The filter (objectClass=*) simply says that all objects within the context scope will be searched. The format of an LDAP filter string is the ABNF format described in RFC 2254. The ABNF format allows an LDAP filter to be as simple as searching all objects or as complex as necessary. Standard operators such as ‘=‘, ‘>’, ‘<‘, etc. can also be used to form an LDAP filter string.

See examples

require valid-user

If this directive exists, mod_auth_ldap grants access to any user that has successfully authenticated during the search/bind phase.

require user

The require user directive specifies what usernames can access the resource. Once mod_auth_ldap has retrieved a unique DN from the directory, it does an LDAP compare operation using the username specified in the require user to see if that username is part of the just-fetched LDAP entry. Multiple users can be granted access by putting multiple usernames on the line, separated with spaces. If a username has a space in it, then it must be surrounded with double quotes. Multiple users can also be granted access by using multiple require user directives, with one user per line. For example, with a AuthLDAPURL of ldap://ldap/o=Airius?cn (i.e., cn is used for searches), the following require directives could be used to restrict access:

require user "Barbara Jenson"
require user "Fred User"
require user "Joe Manager"

Because of the way that mod_auth_ldap handles this directive, Barbara Jenson could sign on as Barbara Jenson, Babs Jenson or any other cn that she has in her LDAP entry. Only the single require user line is needed to support all values of the attribute in the user's entry.

If the uid attribute was used instead of the cn attribute in the URL above, the above three lines could be condensed to

require user bjenson fuser jmanager

require group

This directive specifies an LDAP group whose members are allowed access. It takes the distinguished name of the LDAP group. Note: Do not surround the group name with quotes. For example, assume that the following entry existed in the LDAP directory:

dn: cn=Administrators, o=Airius
objectClass: groupOfUniqueNames
uniqueMember: cn=Barbara Jenson, o=Airius
uniqueMember: cn=Fred User, o=Airius

The following directive would grant access to both Fred and Barbara:

require group cn=Administrators, o=Airius

Behavior of this directive is modified by the AuthLDAPGroupAttribute and AuthLDAPGroupAttributeIsDN directives.

require dn

The require dn directive allows the administrator to grant access based on distinguished names. It specifies a DN that must match for access to be granted. If the distinguished name that was retrieved from the directory server matches the distinguished name in the require dn, then authorization is granted. Note: do not surround the distinguished name with quotes.

The following directive would grant access to a specific DN:

require dn cn=Barbara Jenson, o=Airius

Behavior of this directive is modified by the AuthLDAPCompareDNOnServer directive.

require valid-user

If this directive exists, mod_auth_ldap grants access to any user that has successfully authenticated during the search/bind phase.

require user

The require user directive specifies what usernames can access the resource. Once mod_auth_ldap has retrieved a unique DN from the directory, it does an LDAP compare operation using the username specified in the require user to see if that username is part of the just-fetched LDAP entry. Multiple users can be granted access by putting multiple usernames on the line, separated with spaces. If a username has a space in it, then it must be surrounded with double quotes. Multiple users can also be granted access by using multiple require user directives, with one user per line. For example, with a AuthLDAPURL of ldap://ldap/o=Airius?cn (i.e., cn is used for searches), the following require directives could be used to restrict access:

require user "Barbara Jenson"
require user "Fred User"
require user "Joe Manager"

Because of the way that mod_auth_ldap handles this directive, Barbara Jenson could sign on as Barbara Jenson, Babs Jenson or any other cn that she has in her LDAP entry. Only the single require user line is needed to support all values of the attribute in the user's entry.

If the uid attribute was used instead of the cn attribute in the URL above, the above three lines could be condensed to

require user bjenson fuser jmanager

require group

This directive specifies an LDAP group whose members are allowed access. It takes the distinguished name of the LDAP group. Note: Do not surround the group name with quotes. For example, assume that the following entry existed in the LDAP directory:

dn: cn=Administrators, o=Airius
objectClass: groupOfUniqueNames
uniqueMember: cn=Barbara Jenson, o=Airius
uniqueMember: cn=Fred User, o=Airius

The following directive would grant access to both Fred and Barbara:

require group cn=Administrators, o=Airius

Behavior of this directive is modified by the AuthLDAPGroupAttribute and AuthLDAPGroupAttributeIsDN directives.

require dn

The require dn directive allows the administrator to grant access based on distinguished names. It specifies a DN that must match for access to be granted. If the distinguished name that was retrieved from the directory server matches the distinguished name in the require dn, then authorization is granted. Note: do not surround the distinguished name with quotes.

The following directive would grant access to a specific DN:

require dn cn=Barbara Jenson, o=Airius

Behavior of this directive is modified by the AuthLDAPCompareDNOnServer directive.

require valid-user

If this directive exists, mod_auth_ldap grants access to any user that has successfully authenticated during the search/bind phase.

require user

The require user directive specifies what usernames can access the resource. Once mod_auth_ldap has retrieved a unique DN from the directory, it does an LDAP compare operation using the username specified in the require user to see if that username is part of the just-fetched LDAP entry. Multiple users can be granted access by putting multiple usernames on the line, separated with spaces. If a username has a space in it, then it must be surrounded with double quotes. Multiple users can also be granted access by using multiple require user directives, with one user per line. For example, with a AuthLDAPURL of ldap://ldap/o=Airius?cn (i.e., cn is used for searches), the following require directives could be used to restrict access:

require user "Barbara Jenson"
require user "Fred User"
require user "Joe Manager"

Because of the way that mod_auth_ldap handles this directive, Barbara Jenson could sign on as Barbara Jenson, Babs Jenson or any other cn that she has in her LDAP entry. Only the single require user line is needed to support all values of the attribute in the user's entry.

If the uid attribute was used instead of the cn attribute in the URL above, the above three lines could be condensed to

require user bjenson fuser jmanager

require group

This directive specifies an LDAP group whose members are allowed access. It takes the distinguished name of the LDAP group. Note: Do not surround the group name with quotes. For example, assume that the following entry existed in the LDAP directory:

dn: cn=Administrators, o=Airius
objectClass: groupOfUniqueNames
uniqueMember: cn=Barbara Jenson, o=Airius
uniqueMember: cn=Fred User, o=Airius

The following directive would grant access to both Fred and Barbara:

require group cn=Administrators, o=Airius

Behavior of this directive is modified by the AuthLDAPGroupAttribute and AuthLDAPGroupAttributeIsDN directives.

require dn

The require dn directive allows the administrator to grant access based on distinguished names. It specifies a DN that must match for access to be granted. If the distinguished name that was retrieved from the directory server matches the distinguished name in the require dn, then authorization is granted. Note: do not surround the distinguished name with quotes.

The following directive would grant access to a specific DN:

require dn cn=Barbara Jenson, o=Airius

Behavior of this directive is modified by the AuthLDAPCompareDNOnServer directive.

require valid-user

If this directive exists, mod_auth_ldap grants access to any user that has successfully authenticated during the search/bind phase.

require user

The require user directive specifies what usernames can access the resource. Once mod_auth_ldap has retrieved a unique DN from the directory, it does an LDAP compare operation using the username specified in the require user to see if that username is part of the just-fetched LDAP entry. Multiple users can be granted access by putting multiple usernames on the line, separated with spaces. If a username has a space in it, then it must be surrounded with double quotes. Multiple users can also be granted access by using multiple require user directives, with one user per line. For example, with a AuthLDAPURL of ldap://ldap/o=Airius?cn (i.e., cn is used for searches), the following require directives could be used to restrict access:

require user "Barbara Jenson"
require user "Fred User"
require user "Joe Manager"

Because of the way that mod_auth_ldap handles this directive, Barbara Jenson could sign on as Barbara Jenson, Babs Jenson or any other cn that she has in her LDAP entry. Only the single require user line is needed to support all values of the attribute in the user's entry.

If the uid attribute was used instead of the cn attribute in the URL above, the above three lines could be condensed to

require user bjenson fuser jmanager

require group

This directive specifies an LDAP group whose members are allowed access. It takes the distinguished name of the LDAP group. Note: Do not surround the group name with quotes. For example, assume that the following entry existed in the LDAP directory:

dn: cn=Administrators, o=Airius
objectClass: groupOfUniqueNames
uniqueMember: cn=Barbara Jenson, o=Airius
uniqueMember: cn=Fred User, o=Airius

The following directive would grant access to both Fred and Barbara:

require group cn=Administrators, o=Airius

Behavior of this directive is modified by the AuthLDAPGroupAttribute and AuthLDAPGroupAttributeIsDN directives.

require dn

The require dn directive allows the administrator to grant access based on distinguished names. It specifies a DN that must match for access to be granted. If the distinguished name that was retrieved from the directory server matches the distinguished name in the require dn, then authorization is granted. Note: do not surround the distinguished name with quotes.

The following directive would grant access to a specific DN:

require dn cn=Barbara Jenson, o=Airius

Behavior of this directive is modified by the AuthLDAPCompareDNOnServer directive.

Util_LDAP which also goes by the name of Mod_LDAP, is a module that provides common LDAP services for other LDAP based modules. At this time the only LDAP module that is built on top of Util_LDAP is mod_Auth_LDAP. Util_LDAP provides an interface that handles connecting to and caching connections to the LDAP server as well as checking user credentials against the LDAP directory and caching the credentials for quick look up during subsequent queries. Util_LDAP also supports SSL encrypted connections to the LDAP server.

There are a number of directives that are implemented by the Util_LDAP module. These directives control performance of the operations caches and secure connections to the LDAP server.

Establishing a secure connection to the LDAP server requires the use of certificates. The LDAPTrustedCA and LDAPTrustedCAType directives provide Util_LDAP with the certificate information so that it can securely authenticate and establish the connection. Establishing a secure connection to the LDAP server requires that the value of the AuthLDAPURL directive change to show that a secure connection is requested. This change includes specifying “ldaps://” rather than “ldap://” as the protocol. The default secure port used by the LDAP server is port 636 as opposed to the unsecure port 389. If you are connecting to port 636, you do not need to include it as part of the secure LDAP URL. But if you wish to establish a secure connection to another LDAP port, the alternate port must be included in the LDAP URL along with the secure LDAP protocol specifier (“ldaps://”)

All of the supported LDAP SDKs support SSL encrypted connections to an LDAP server. The main issue is that all of them implement the SSL connection APIs differently. This difference is the main reason why you will see #ifdef’s within the Util_LDAP code. The good news is that the API differences have been hidden behind the directives so that users don’t have to worry about them. With the exception of the way that the certificate files are specified. Both the OpenLDAP and Novell LDAP SDK’s expect a path to a certificate file to be defined. The difference between the OpenLDAP and the Novell LDAP SDKs is that OpenLDAP will only accept BASE64_FILE type certificates. The iPlanet LDAP SDK expects all of the certificates to be bundled into a CERT7_DB_FILE and will not accept any other type. The Microsoft SDK extracts the certificate from it’s own certificate store found in the Windows registry.

In order to accommodate the multi-process environment in which Apache is run on Linux and other operating systems, the operation caches are created and maintained in shared memory. These shared memory caches have been one of the major obstacles that has prevented mod_auth_ldap and util_ldap from moving out of the experimental classification into a fully functional shipping module. In the last few months a lot of work as been done to stabilize this portion of the util_ldap code. For that reason as well as several other bug fixes, mod_auth_ldap and util_ldap are no longer classified as experimental in Apache 2.1/2.2.

Since it can be difficult to debug through the credential and operation caches, Util_LDAP also provides a cache status display. You can enable the cache status display by adding the “ldap-status” handler.

<Location /cache-status>

AddHandler ldap-status

</Location>

It would probably be a good idea to also use mod_auth_ldap to restrict access to the cache status display to only those with valid credentials.

Shows the main page of the cache status display. Shows each configured LDAP URL as well as a link to the LDAP URL cache itself. If you click on the “LDAP URL Cache” link, it will display more details about the exact contents of the LDAP URL cache. Clicking on each of the LDAP URLs will display additional details about the contents of the respective caches.

Shows the details of the SEARCH-NODE Cache-Nodes. From this display you can see what filters where enabled for which users and the last time that a valid bind was done.

There has been a lot of changes to Mod_Auth_LDAP and Util_LDAP for Apache 2.1/2.2. The configuration of these modules is basically the same but there are enough differences to make the 2.0 version incompatible with the 2.1/2.2 version. As was mentioned at the beginning of this presentation, Mod_Auth_LDAP and Util_LDAP are no longer experimental modules. In addition, Mod_Auth_LDAP and Util_LDAP have been restructured to fit with the new auth module architecture. In this new architecture, the job of authentication and authorization has been modularized. Mod_Auth_LDAP and Util_LDAP no longer need to implement all aspects of authentication and authorization. In fact you can now mix and match auth modules in such a way that authentication can be done against an LDAP directory and authorization against a local file or vice-versa. One thing to note is that due to shared connections and caching, the LDAP Authentication and Authorization functionality had to remain within a single module called Mod_Authnz_LDAP rather than being split apart into an authentication module and an authorization module similar to other auth modules.

The major difference between the configuration of the original Mod_Auth_LDAP and the new Mod_Authnz_LDAP is in the authorization directives. Rather than using “user”, “group” and “dn” as before, you must now use “ldap-user”, “ldap-group” and “ldap-dn” instead. The reason for this is because “user”, “group” and “dn” have been defined by other authorization modules and to avoid a conflict, the Mod_Authnz_LDAP authorization types had to be renamed. This does not mean that “user”, “group”, and “dn” can not be used. In fact they can and should if you want to mix and match authentication types with authorization types. But if you decide to use an authorization type that is not implemented by Mod_Authnz_LDAP, such as “valid-user”, you must make sure that AuthzLDAPAuthoritative is set to OFF. This will allow Mod_Authnz_LDAP to defer authorization to other modules.

Apache/Tomcat Configuration

2003-12-08T12:43:39