IBM HTTP Server Questions and Answers

Questions which apply to all levels of IBM HTTP Server

Is IBM HTTP Server release supported on platform?

For this IBM HTTP Server release... Check here...
1.3.26.2 WebSphere Application Server V5.0.2 software requirements
1.3.28.1 WebSphere Application Server V5.1.1 software requirements
2.0.42.2 WebSphere Application Server V5.0.2 software requirements
2.0.47.1 WebSphere Application Server V5.1.1 software requirements
6.0.2 WebSphere Application Server V6.0.2 - detailed system requirements
6.1 List of supported software for WebSphere Application Server V6.1

Can IBM HTTP Server release x be used with WebSphere release y?

There are two issues of compatibility:

  1. The WebSphere plug-in used in the web server must be compatible with the release of WebSphere. A table is provided in the Web server plug-in policy technote.
  2. The WebSphere plug-in must be compatible with the release of IBM HTTP Server. The best way to accomplish this is by using the plug-in from the same WebSphere release as IBM HTTP Server.

Refer to this documentation:

Is IBM HTTP Server installed with WebSphere?

What are the product lifecycle dates for IBM HTTP Server?

What release of Apache is IBM HTTP Server based on?

IBM HTTP Server release corresponding Apache release that it was based on corresponding WebSphere Application Server release
1.3.12.x 1.3.12 3.5.x
1.3.19.x 1.3.20 4.0.x
1.3.26.x 1.3.26 5.0.x
1.3.28.x 1.3.28 5.1.x
2.0.42 2.0.42 5.0
2.0.42.1 2.0.44 Fix pack 5.0.1
2.0.42.2 2.0.46 Fix pack 5.0.2
2.0.42.2-PQ85834 and later 2.0.47 N/A
2.0.47 and later 2.0.47 5.1
6.0 2.0.47 6.0
6.1 2.0.47 6.1

Note: Fixes from later levels of Apache are also included. The Apache releases above should be referred to for the purposes of third-party module compatibility as well as determining the base level of Apache fixes included, before additional fixes were incorporated to resolve specific customer problems.

Is a specific Apache fix in my level of IBM HTTP Server?

First, check the previous table which lists the level of Apache on which your level of IBM HTTP Server is based.

IBM HTTP Server release How to check
6.0 and above Look in install_root/readme/CHANGES_HTTPD for the Apache CHANGES text. Apache CHANGES entries are copied there when a fix from a later level of Apache is integrated.
If the Apache CHANGES entry is in CHANGES_HTTPD, then your level of IBM HTTP Server has the fix.
1.3, 2.0 Check the readme.txt associated with the last cumulative e-fix which was applied. Those have one-line extracts of the Apache CHANGES entries, so the text won't match exactly.

What is the sequence of cumulative fix packages for IBM HTTP Server 2.0.42.2 and 2.0.47.1?

Cumulative fix packages for these releases use an APAR number for the fix level instead of a higher version number. Support documentation often lists the first fix package which resolves a defect; e.g., PK07831 or later. The table below, which provides the order of the fix packages, can be used to determine if the defect is already corrected in your level of IBM HTTP Server. If a later fix package has already been applied, the defect is already resolved.

APAR number Date of release Notes
PQ85834 Q2 2004 2.0.42.x users must install this or PQ87339 in order to apply later maintenance.
2.0.47 users should install 2.0.47.1 instead of this.
PQ87339 Q2 2004 This is needed only for Solaris users with certain levels of GSKit installed.
PQ90698 Q3 2004  
PQ94086 Q3 2004  
PQ94389 Q4 2004  
PK01070 Q1 2005  
PK07831 Q3 2005  
PK13230 Q4 2005  
PK25355 Q2 2006  
PK29827 August 21, 2006  

When a defect needs to be resolved, always apply the current recommended update instead of the first fix package that contained the fix.

What is the sequence of cumulative fix packages for IBM HTTP Server 1.3.26.2 and 1.3.28.1?

Cumulative fix packages for these releases use an APAR number for the fix level instead of a higher version number. Support documentation often lists the first fix package which resolves a defect; e.g., PK05084 or later. The table below, which provides the order of the fix packages, can be used to determine if the defect is already corrected in your level of IBM HTTP Server. If a later fix package has already been applied, the defect is already resolved.

1.3.28.1
APAR number Date of release
PQ90262 August 31, 2004
PQ98444 January 28, 2005
PK05084 May 9, 2005
PK16139 January 16, 2006
PK27875 August 10, 2006

1.3.26.2
APAR number Date of release
PQ87084 May 13, 2004
PQ90262 August 31, 2004
PK05084 May 9, 2005
PK16139 January 16, 2006
PK27875 August 10, 2006

When a defect needs to be resolved, always apply the current recommended update instead of the first fix package that contained the fix.

What is the difference between WebSphere keep-alive settings and IHS keep-alive settings?

IHS keepalive settings affect connections between IHS and the web client. WebSphere settings affect connections between the WebSphere plug-in (running in IHS) and WebSphere. The connections are independent and the settings are independent.

When does KeepAliveTimeout period start, relative to sending the response to the previous request to the client?

Does it start counting when IHS sent a response back to the client, or does the timeout period start when client ACKed the response?

It could be at either point, depending on the situation. IHS will start measuring the KeepAliveTimeout as soon as it successfully queues all of the previous HTTP response to the TCP layer. The operating system TCP layer sits between IHS and the network (client). IHS isn't aware of some network flows such as ACK flows, but it is affected by ACK flows.

Requests handled by WebSphere plug-in aren't authenticated. WebSphere plug-in doesn't send user id to WebSphere. Why not?

When enabling authentication in IHS, be aware that some configuration mechanisms apply only to static files served by IHS but not to requests handled by the WebSphere plug-in.

Example 1:

<Directory /usr/HTTPServer/htdocs/en_US>
AuthType Basic
AuthName WebAccess
AuthUserFile /usr/HTTPServer/userids
Require valid-user
</Directory>

This type of configuration only affects files served by IHS, because the Directory keyword is used. It does not affect WebSphere requests.

Similarly, rules in a .htaccess file can only control access to files served by IHS. They do not apply to proxy or WebSphere requests.

Example 2:

<Location />
AuthType Basic
AuthName WebAccess
AuthUserFile /usr/HTTPServer/userids
Require valid-user
</Location>

This type of configuration affects any request for that location served by IHS, including WebSphere requests, because the Location keyword is used. The WebSphere plug-in would then pass the user id on to WebSphere for possible use by the application.

Why does the web browser present an authentication prompt twice when loading the same page?

Watch out for redirections which make the web browser think it is contacting a different web server. Here is an example of this type of problem, where the web browser has to authenticate over non-SSL only to find out that it has been redirected to an SSL port. The browser assumes that it is a different server and will prompt again.

<Location /protected.html>
RewriteEngine on
RewriteCond %{SERVER_PORT} =80
RewriteRule ^(.*) https://%{SERVER_NAME}%{REQUEST_URI}
Satisfy all
AuthUserFile /etc/webusers
AuthName Intranet
AuthType basic
Require valid-user
</Location>

In this type of situation, the redirection to SSL should be unauthenticated. Then, the authentication should happen once the request has been issued to the SSL port. Here is a solution:

# when request for the protected resource is received over 
# non-SSL, redirect to SSL without authenticating
<VirtualHost *:80>
...       (existing configuration for this vhost)
<Location /protected.html>
RewriteEngine on
RewriteRule ^(.*) https://%{SERVER_NAME}%{REQUEST_URI}
</Location>
</VirtualHost>

# when request for the protected resource is received over
# SSL, authenticate
<VirtualHost *:443>
...       (existing configuration for this vhost)
<Location /protected.html>
Satisfy all
AuthUserFile /etc/webusers
AuthName Intranet
AuthType basic
Require valid-user
</Location>
</VirtualHost>

Can IBM HTTP Server modify Cookie or other request header fields?

mod_headers is provided and allows some limited request header modification. It can:

No other manipulation is provided.

A custom plug-in module would have to be used if a different type of manipulation is required within IBM HTTP Server, including removing individual cookies from a Cookie header field.

How can I log a response header field such as Set-Cookie?

This is with the LogFormat directive. The format string to use is "%{header-name}o", or "%{Set-Cookie}o".

Simple example for this existing access log configuration:

LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog logs/access_log common

Add "%{Set-Cookie}o" to the format string on the LogFormat directive, resulting in

LogFormat "%h %l %u %t \"%r\" %>s %b %{Set-Cookie}o" common
CustomLog logs/access_log common

(There may be a number of different LogFormat directives... the one of interest is the one whose format name (e.g., "common") is actually referenced on your CustomLog directive.)

Do I have to start IBM HTTP Server as root?

Port access on Unix and Linux

Applications running as users other than root are normally prevented from binding to (listening on) low-numbered ports on Unix and Linux systems. Low-numbered ports are those ports below 1024. The standard ports for most popular Internet protocols, including http and https, are low-numbered ports.

On Solaris 10, IBM HTTP Server must be started as root to bind to a low-numbered port unless the user which starts the web server has been granted the net_privaddr privilege.

On AIX, HP-UX, and Linux, and other versions of Solaris, IBM HTTP Server must be started as root to bind to a low-numbered port. A possible work-around is to utilize a firewall to redirect requests to port 80 to a high port. The web server will listen on the high-numbered port, thus avoiding the root requirement.

Port access on z/OS

z/OS can restrict low ports to UID(0) users or authorized programs, allow reservation of particular ports to specified users or jobs, or allow unrestricted access. We recommend that IBM HTTP Server be started as a non-UID(0) user and z/OS configuration used to allow access to the required ports. Refer to Performing required z/OS system configurations in the IBM HTTP Server InfoCenter for more information.

Log and configuration file access

The user id starting the web server must have read access to the configuration files and write access to the directory containing log files and other run-time files. This may require starting as root, or changing the ownership or permission of existing log files, depending on the configuration.

Can IBM HTTP Server serve files larger than 2GB?

IBM HTTP Server version Platform Can files larger than 2GB be served?
1.3.x all platforms No
2.0.x Windows Yes
2.0.x AIX, Linux, HP-UX, Solaris No
6.0.x, 6.1.x Windows, HP-UX/ia64, Solaris/x64, z/OS (only provided for 6.1.x) Yes
6.0.x, 6.1.x AIX, Linux, HP-UX/PA-RISC, Solaris/SPARC No

Supporting files larger than 2GB is theoretically possible on other version/platform combinations, but it breaks binary compatibility with plug-in modules, so the change cannot be made. 64-bit versions of IBM HTTP Server support files larger than 2GB.

Can IBM HTTP Server write to log files over 2GB?

IBM HTTP Server 2.0.42.x and later

Windows

IBM HTTP Server 2.0.42.x and later on Windows can write to log files > 2GB.

Unix and Linux

This is supported, except for rotatelogs, with cumulative i-fix PK01070 or later for 2.0.42.2 and 2.0.47.1, and with IHS 6.0.0.2 and later.

Why does rotatelogs still not support large files?

The web server and rotatelogs use file access interfaces provided by the Apache Portable Runtime (APR) library bundled with IBM HTTP Server. The APR provided with IBM HTTP Server on these platforms cannot support file offsets larger than 2GB without introducing an API incompatibility, which would break all current plug-in modules written for IBM HTTP Server. However, it was possible to enable large file support for applications which only append to files without introducing an API incompatibility.

The web server's internal support for error and access log files only appends to the end of log files and does not use file offsets, so the modifications to APR allow large log files when using the internal web server support.

The rotatelogs application interacts with log files in a more complex manner, including the use of file offsets. Thus, the APR changes don't enable large file support in rotatelogs.

IBM HTTP Server 1.3.x

Unix and Linux

This will not be supported. The work-around is to configure rotatelogs or another piped log program to switch log files before they reach 2GB.

# Original access log definition: CustomLog /usr/HTTPServer/logs/access_log common
# This will create files called "access.timestamp", such as access.1136764800,
# and rotate every 24 hours (86400 seconds).
CustomLog "|/usr/HTTPServer/bin/rotatelogs /usr/HTTPServer/logs/access 86400" common

cronolog is a fully featured piped log program from a third party which has many more features for managing log files.

Are there tools to analyze IBM HTTP Server access logs?

IHS doesn't include any such tools, but there are numerous third-party solutions for log file analysis. Search for "Apache log file analyzer" using your favorite Internet search engine.

We are aware that some IHS customers are successfully using Webalizer, a freely-distributed application available from http://www.mrunix.net/webalizer/.

I don't want anybody to know what server I'm running. What can I do?

You can't prevent the product name from being sent to clients in the Server header field, but you can minimize it to

Server: IBM_HTTP_SERVER

by coding

ServerTokens Prod

in the web server configuration file.

See also the ServerSignature directive for controlling whether information about the server is included in certain error messages.

Even without the standard Server header field in the response:

IHS 2.0.42.x prior to PQ85834 had a defect which allowed CGIs and plug-ins to override the value of the Server header field.

How can I start IHS automatically at boot time on AIX?

Here are AIX inittab entries to start IHS 1.3 or IHS 2.0:

: ihshttpd:2:wait:/usr/HTTPServer/bin/httpd > /dev/console 2>&1     
ihshttpd:2:wait:/usr/IBMIHS/bin/apachectl start > /dev/console 2>&1 

The first entry is commented out (leading ":") and starts IHS 1.3. The second entry is active and starts IHS 2. For either 1.3 or 2.0, replace the path to httpd or apachectl with the chosen installation directory. The "apachectl start" command is a valid way to start IHS 1.3 or IHS 2.0. The "httpd" command is only valid for IHS 1.3.

Why are httpd processes still active when apachectl stop completes?

apachectl stop sends a signal to the parent process, and then exits. As soon as the parent process receives the signal, it starts terminating the child processes. In many cases, by the time you can look for child processes after the completion of apachectl stop they will have already exited. Some of the following are reasons why they will linger for some time:

If a shutdown problem is suspected with IBM HTTP Server 2.0 or above, make sure that you are using one of the following software levels:

6.1
GA
6.0.x
6.0.0.2 or later
2.0.42.x, 2.0.47.x
PK01070 or later

How can I save mod_status page at intervals?

When customers can't get to mod_status page from a browser, or when there is some load balancer in front that makes it difficult to get mod_status from a particular server, or when they want to have mod_status pages saved automatically, they can run something like this script on the web server system. It requires that perl and wget be installed. Perl usually comes with the operating system, and wget is an open source program to save a web page in a file.

grabstatus.pl:

#!/usr/bin/perl -w

use strict;

my $STATUS_URL = "http://127.0.0.1/server-status/";
my $SLEEP_INTERVAL = 60; # seconds

while (1) {
  my $timestamp = time();

  system("wget -O serverstatus.$timestamp $STATUS_URL");

  sleep($SLEEP_INTERVAL);
}

If all you want is to know how many threads are busy and in what state, see mod_mpmstats.

How can I configure IBM HTTP Server to serve filename.html when the browser requests filename?

The mod_negotiation MultiViews feature can automatically select a file with appropriate extension when the browser does not provide a file extension.

Configuration:

LoadModule negotiation_module modules/mod_negotiation.so
...
<Directory /prefix-for-multiviews/>
Options +MultiViews
</Directory>

How can I disable caching in Internet Explorer?

Use mod_headers with the following configuration:

  Header set Pragma "no-cache"
  Header set Cache-Control "no-cache"
  Header set Expires "-1"

How can I disable the HTTP TRACE method?

Refer to this document.

How can I downgrade the server response to HTTP/1.0 for certain requests?

<Location /some/url>
SetEnv downgrade-1.0 1                                                  
</Location>

How can I rotate (switch) log files?

Piped log programs

(all platforms)

This uses rotatelogs or a third-party replacement such as cronolog. IBM HTTP Server sends log records to an external program, referred to as a piped logger, which is responsible for switching to a new log file when certain criteria are met.

Refer to the Piped Logs section of the documentation for more information.

Renaming log files and restarting

(Linux and Unix platforms only)

This method renames log files while the web server is running and still writing to the old files then restarts the web server to open files under the normal name again.

Refer to the Log Rotation section of the documentation for more information.

Other methods may be equally effective, but if you are having troubles with a different method or a script provided by a third party, please use the documented methods before contacting IBM support for help resolving the problem.

Does rotatelogs rotate log files if no requests are received?

No, the rotate operation will not occur until IHS logs another request. If your configuration specifies that rotatelogs performs the rotation operation after 86400 seconds, and if IHS receives no requests after 86400 seconds have elapsed, the new log file will not yet be created. Then, when rotatelogs receives its next request to log, it will create the new log file and close the old one.

Does rotatelogs buffer data before writing to the log file?

No. However, data may be buffered in the operating system kernel after the web server writes the data but before rotatelogs can read it. This time is usually very brief.

Other programs can be used to filter data seen by rotatelogs, and those programs may introduce buffering. Example:

CustomLog "|grep -v \b200\b | /opt/IHS/bin/rotatelogs /opt/IHS/logs/grepped 86400 540" common

In this case, grep will buffer data internally until it has a full buffer, then rotatelogs will see many log records at the same time. (4096 bytes is a typical size for the buffer used by grep.)

Note: IBM HTTP Server 6.0 prior to 6.0.2.1, or IBM HTTP Server 2.0 prior to PK07831, does not support the type of CustomLog directive in the example above.

I have the LockFile directive specified, but I can't see the lock file in the filesystem. Why not?

Short answer: This is working as designed; the lock file doesn't show up in directory listing except for a brief moment during IHS initialization.

Long answer: When IHS initializes an fcntl accept mutex during startup, it opens/creates the lock file, retains the file descriptor, but "unlinks" the lock file so that it is removed from the system just in case IHS exits abnormally and is unable to run its normal cleanup code. This procedure is a standard technique to avoid leaving dangling files after process termination, but it results in the file being invisible to the ls command. This means that other applications can't mess with the file, accidentally or not, since they can never open the same lock file used by IHS.

If you really want to see the lock file working, you can pick an IHS child process and run truss against it. ("truss -p PID") At the end of processing one client, a call like this will appear:

kfcntl(19, F_SETLKW, 0x2000AEE0) (sleeping...)

So file descriptor 19 is the lock file. (This actual number will almost certainly be different in your environment.) lsof when run against an httpd process ("lsof -p PID") would display that file descriptor as follows:

httpd   23104 root  19w  VREG    10,8   0 2261678 /home (/dev/hd1)

The size (7th column) should be 0 and the filesystem (two last columns) should match the filesystem used by your LockFile directive.

What are these requests for file favicon.ico in my logs?

A customer sees something like this in his access log:

127.0.0.1 - - [08/Mar/2005:12:51:08 -0500] "GET /favicon.ico HTTP/1.1" 404 304

Requests for favicon.ico are unavoidable. Internet Explorer and some other browsers will blindly request favicon.ico in case the web site has that file. You may have noticed that on some web sites, there is a cute icon in the URL box on your web browser; favicon.ico from that web site is the cute icon. Most web sides don't have that file, so there will be a 404 in the web site's access log and the browser will use the default icon.

The customer is not in control of whether or not the browser issues that request. They can have their site designer provide a favicon.ico file or they can ignore the entries in the access log. We do not recommend that they filter out the entries from the access log, because if there is ever a question of what requests are hitting the server, then the access log wouldn't be able to answer that question.

Why do I get 403 Forbidden trying to view server-status reports?

There are two common problems:

  1. The server status page is protected, and the client doesn't meet the authorization criteria. For example, there may be an allow from directive for <Location /server-status> which is not working.
  2. The configured DocumentRoot directory isn't readable by the web server user id (e.g., nobody). If this is the cause, the error log will have a message like the following:
    [Sat Mar 12 06:36:21 2005] [error] [client 127.0.0.1] (13)Permission denied: access to /server-status/ denied
    

How does IBM HTTP Server determine when a child process should end? Does it have a timeout?

There is no timeout. Beyond normal web server termination or restart, here are the situations where a child process will exit:

All releases of IBM HTTP Server on Windows

A child process will only end if MaxRequestsPerChild is set to non-zero, and the process has handled at least that many client connections.

IBM HTTP Server 1.3.x on Linux and Unix

If MaxRequestsPerChild is set to non-zero, a child process will exit once it has handled that many client connections.

While there are more idle processes than the value of MaxSpareServers, one child process will exit per second.*

*On AIX, if AcceptMutex is set to pthread, idle child process termination often does not work. Code AcceptMutex fcntl to work around this problem.

IBM HTTP Server 2.0 and higher on Linux and Unix

If MaxRequestsPerChild is set to non-zero, a child process will exit once it has handled that many client connections.

While there are more idle threads than the value of MaxSpareThreads, one child process will exit per second.

Linux and Unix: How do I keep IHS from terminating child processes prior to web server shutdown?

Occasionally, problems with IHS or third-party modules can be attributed to issues which occur when IHS child processes terminate. In this case, it is helpful to disable child process termination until the problem can be fully resolved.

IHS 2.0 and above

Set MaxRequestsPerChild to 0 and set MaxSpareThreads to the same value as MaxClients.

IHS 1.3

Set MaxRequestsPerChild to 0 and set MaxSpareServers to the same value as MaxClients.

How do you gracefully shut down IHS?

There is no mechanism to shut down the web server yet allow active requests to gracefully finish. Active requests must finish within about 7 seconds, or they may be forcefully terminated when the child process is killed.

Is IBM HTTP Server 32-bit or 64-bit? Will 32-bit IBM HTTP Server run on my 64-bit OS? Which WebSphere plug-in fix pack should I use?

IBM HTTP Server is a 64-bit application on HP-UX/ia64 and Solaris/x64. IBM HTTP Server is a 32-bit* application on other platforms. Many platforms, including AIX, HP-UX, Solaris, and 64-bit Linux, provide support for both 32-bit and 64-bit applications, so a 32-bit IBM HTTP Server is able to function properly even though other applications on the system may be 64-bit.

Customers with certain 64-bit Linux platforms must ensure that they have installed 32-bit application support. The package selection varies by vendor.

WebSphere plug-in

Beginning with WebSphere 6.0.1, WebSphere provides 64-bit support for the application server and the plug-in on some platforms where IBM HTTP Server continues to provide only 32-bit support. In these cases, customers must ensure that they use the 32-bit plug-in with IBM HTTP Server. A 32-bit IBM HTTP Server and WebSphere plug-in has no functional limitations when communicating with a 64-bit application server.

GSKit, ikeyman, and Java

SSL and LDAP support in IBM HTTP Server use GSKit for cryptography. When IBM HTTP Server is 32-bit, a 32-bit GSKit will be installed with IBM HTTP Server. When IBM HTTP Server is 64-bit, a 64-bit GSKit will be installed with IBM HTTP Server.

ikeyman requires a Java and a GSKit which match with regards to 32-bit or 64-bit.. Generally, a Java of the same flavor as IBM HTTP Server will be installed, so ikeyman uses the same GSKit as IBM HTTP Server.

Exception: IBM HTTP Server 6.0.2 on Solaris/x64: IBM HTTP Server is 64-bit and thus requires 64-bit GSKit. The installed Java is 32-bit and thus ikeyman requires a 32-bit GSKit. So both 32-bit and 64-bit GSKit are installed with IBM HTTP Server.

(* or 31-bit IBM HTTP Server for Linux on zSeries hardware)

Summary

IBM HTTP Server releases prior to 6.0 are 32-bit applications on all platforms*.

IBM HTTP Server 6.0 and 6.1:

Platform Mode Plug-in fix pack to download Special notes
AIX 32-bit 32-bit Power PC Plug-ins The application server and plug-ins are available in both 32-bit and 64-bit versions for this platform.
HP-UX/ia64 64-bit 64-bit Intel Itanium Plug-ins  
HP-UX/PA-RISC 32-bit 32-bit HP PA-RISC Plug-ins  
Linux/PPC 32-bit i/p Series Plug-ins The application server and plug-ins are available in both 32-bit and 64-bit versions for this platform.
Linux/s390 31-bit zSeries Plug-ins The application server and plug-ins are available in both 31-bit and 64-bit versions for this platform.
Linux/x86 32-bit 32-bit x86 AMD/Intel Plug-ins The application server and plug-ins are available in both 32-bit and 64-bit versions for this platform.
Solaris/SPARC 32-bit SUN SPARC 32-bit Plug-ins The application server and plug-ins are available in both 32-bit and 64-bit versions for this platform.
Solaris/x64 64-bit Solaris x86 64-bit Plug-ins  
Windows for x86 AMD/Intel 32-bit 32-bit x86 AMD/Intel Plug-ins The application server and plug-ins are available in both 32-bit and 64-bit versions for this platform.
z/OS 64-bit PTFs for component id 5655I3511 Support for this platform was introduced in 6.1.0.4.

mod_rewrite: How can I redirect all non-SSL requests to SSL?

Here is an example where all requests received on port 80 are redirected to the SSL port. Replace www.example.com with the hostname of your server. The new VirtualHost container will automatically apply to any requests received on the specified port (80), and mod_rewrite will always redirect these requests to the https (SSL) equivalent.

<VirtualHost *:80>
RewriteEngine on
RewriteRule ^/(.*) https://www.example.com/$1 [R,L]
</VirtualHost>

mod_rewrite: a character in my new URL is being escaped as %nn. How can I avoid that?

Example: The following RewriteRule is supposed to redirect requests for /datasheets to http://www.example.com/CatalogView?view=01&content=02#readme, but the # is getting translated to %23 in the response to the browser.

RewriteRule /datasheets http://www.example.com/CatalogView?view=01&content=02#readme

By default, mod_rewrite will perform URI escaping on special characters such as '#', such that the rewritten URL contains the percent sign followed by the numeric code for the character. The escaping behavior can be overridden with the noescape processing flag. Here is the new RewriteRule which avoids the escaping:

RewriteRule /datasheets http://www.example.com/CatalogView?view=01&content=02#readme [R,NE]

Consult the mod_rewrite documentation for more information.

Note: If there is a question about what is being sent to the browser, the RewriteLog and RewriteLogLevel directives can be used to turn on logging in mod_rewrite, or the Location header field can be logged in the access log by adding %{Location}o to the access log format.

mod_rewrite: My rules are ignored. Nothing is written to the rewrite log.

The most common cause of this is placing mod_rewrite directives at global scope (outside of any VirtualHost containers) but expecting the directives to apply to requests which were matched by a VirtualHost container.

In this example, the mod_rewrite configuration will be ignored for requests which are received on port 443:

RewriteEngine On
RewriteRule ^index.htm$ index.html

<VirtualHost *:443>
existing vhost directives
</VirtualHost>

Unlike most configurable features, the mod_rewrite configuration is not inherited by default within a <VirtualHost > container. To have global mod_rewrite directives apply to a VirtualHost, add these two extra directives to the VirtualHost container:

<VirtualHost *:443>
existing vhost directives
RewriteEngine On
RewriteOptions Inherit
</VirtualHost>

How can I avoid writing access log records for images?

Set a variable called image-request when the request is for certain filenames. Then, update the CustomLog directive to indicate that requests should not be logged when the image-request variable is set.

SetEnvIf Request_URI \.gif$ image-request
SetEnvIf Request_URI \.jpg$ image-request
# add another SetEnvIf directive for other file extensions to be skipped
CustomLog logs/access_log common env=!image-request

The mod_log_config documentation has an example showing how to put image requests in one access log and non-image requests in another access log.

My request failed with status nnn. How do I find out why?

Generally speaking, requests can fail in one of the following functional areas:

  1. IBM HTTP Server core features (e.g., access was denied, file was not found, etc.)
  2. WebSphere plug-in (e.g., communication error occurred trying to contact the application server)
  3. WebSphere Application Server (e.g., customer application returned a failure due to database problem)
  4. third-party module loaded into IBM HTTP Server failed the request (e.g., couldn't contact LDAP server)

Finding the root cause requires finding which functional area failed the request.

IBM HTTP Server 2.0 and above

These versions have a feature which allows the failing component to be logged:

6.1
GA
6.0.x
6.0.2 and later
2.0.42.x, 2.0.47.x
PK07831 and later

Steps to find the failing component:

  1. Load mod_status:
    LoadModule status_module modules/mod_status.so
    
  2. Enable extended status:
    ExtendedStatus On
    
  3. Add the RH variable to the information logged in access log:
    LogFormat "%h %l %u %t \"%r\" %>s %b %{RH}e" common
    
  4. Recreate the request and check the access log for the failing component:
    127.0.0.1 - - [23/Jan/2006:08:09:51 -0500] "GET /foo.html HTTP/1.1" 404 317 (core.c/404/handler)
    127.0.0.1 - - [23/Jan/2006:08:10:45 -0500] "GET /testcount.jsp HTTP/1.1" 500 644 (mod_was_ap20_http.c/500/handler)
    127.0.0.1 - - [23/Jan/2006:08:11:19 -0500] "GET /cgi-bin/printenv HTTP/1.1" 404 322 (mod_cgid.c/404/handler)
    
    If the module name is... This component failed to handle the request...
    core.c internal web server handling of static files
    mod_was_ap20_http.c WebSphere plug-in
    mod_cgid.c web server support for CGI scripts
    mod_sm.c SiteMinder

    Check the log files of the failing component for more information.

Other levels of IBM HTTP Server

This can usually be determined by checking the log files maintained by the various components.

  1. Check the IBM HTTP Server access log to find the entry for the failing request. Example:
    127.0.0.1 - - [08/Apr/2005:06:40:08 -0400] "GET /cgi-bin/test-cgi" 500 658 -
    
  2. Check the IBM HTTP Server error log for messages at the same time. Example:
    [Fri Apr 08 06:40:08 2005] [error] (13)Permission denied: exec of 'test-cgi' failed
    [Fri Apr 08 06:40:08 2005] [error] [client 127.0.0.1] Premature end of script headers: test-cgi
    

    In this case, an IBM HTTP Server feature failed, and the error log contains more information.

    If no entries were written to the error log at the time of the failure, the problem must have occurred in an area other than IBM HTTP Server. Proceed with the following checks.

  3. Check the WebSphere plug-in trace file for messages at the same time. If the WebSphere plug-in encountered a processing error (e.g., could not connect to the application server), it will be reported to the trace file.

    If no entries were written to the plug-in trace file, the problem must have occurred in a different area. Proceed with the following checks.

  4. Check WebSphere logs for error messages at the same time. Alternately, turn on detailed WebSphere plug-in trace and reproduce the problem. With a detailed plug-in trace, the HTTP status code returned by WebSphere will be traced, and you can see if WebSphere is the source of the failure (e.g., the functional area which returned status code 500).

    If WebSphere didn't process the request, or WebSphere returned a good response code for the request (e.g., 200 or 302), the problem must have occurred in a different area. Proceed with the following checks.

  5. Check logs of third-party modules (modules from non-IBM source loaded into IBM HTTP Server) for error messages reported at the same time. Contact third-party module vendor for explanation.
  6. If all else fails, and the platform is Solaris:

    It is likely that truss can be used to show which module is failing the request. If at all practical, re-configure IHS temporarily to use a single child process for processing client requests. Here is an example with IBM HTTP Server 2.0 or above:

    <IfModule worker.c>
    ThreadLimit         256
    ServerLimit         1
    StartServers         1
    MaxClients         256
    MinSpareThreads     1
    MaxSpareThreads     256
    ThreadsPerChild     256
    MaxRequestsPerChild  0
    </IfModule>
    

    Then start IHS as normal, and find the process id of the two IHS child processes via ps.

    # cat /opt/IBMIHS/logs/httpd.pid
    99999                <- example value
    # ps -ef | grep 99999
    webuser 10001   99999  .....
    webuser 10002   99999  .....
    root    99999   1      .....
    

    These two processes with 99999 for the parent are the two IHS child processes. One will be mod_cgid daemon and one will actually serve requests. We'll just trace both of them to avoid picking the wrong child process.

    # truss -o /tmp/tracefile -u :: -u a.out,\* -p 10001 10002
    (Replace 10001 and 10002 with the actual pids of the IHS child
    processes.)
    

    Next, reproduce the problem.

    Next, interrupt the truss process (<Ctrl>C). The tracing via truss will slow down the web server significantly and will generate a large amount of output, so reproduce the problem and stop the tracing as quickly as possible.

    Here is the type of information we would expect to find. In this example, I have configured mod_access to return 403 (access denied) for a certain request:

    $ grep 403 /tmp/outfile
    11729/27@27:                      <- mod_access:check_dir_access() = 403
    11729/27@27:                    <- ap_run_access_checker() = 403
    11729/27@27:                    <- decl_die() = 403
    11729/27@27:                  <- ap_process_request_internal() = 403
    11729/27@27:                  <- ap_die() = 403
    

    The first place where 403 showed up (i.e., the module which set 403) was mod_access.

    For your situation, search for the bad status code (e.g., 500) in /tmp/outfile and see which module (mod_sm, mod_access, whatever) set the 500. Send in the trace file for us to analyze if it isn't clear which module set 500, or if an IBM-provided module set 500. If the status was set by a third-party module, contact the vendor for diagnosis.

How do I determine which vhost is selected when the request is received?

Add an indication of the selected vhost to your access log format, and then retry the testcase.

Configuration changes:

  1. Add SetEnv vhostname MAIN to the main scope of httpd.conf.
  2. Add SetEnv vhostname UNIQUE-NAME to each VirtualHost container. Make sure UNIQUE-NAME is unique for each virtual host.
  3. Add the vhostname (%{vhostname}e) to the access log format.
  4. Add the target IP address (%A) to the access log format.
  5. Add the value of the ServerName associated with the virtual host which served the request (%v) to the access log format.

Example log format with these changes made:

LogFormat "%h %l %u %t \"%r\" %>s %b %A %v %{vhostname}e" common

Example setting of vhostname:

...
SetEnv vhostname MAIN
...
<VirtualHost something>
...
SetEnv vhostname vhost8443
</VirtualHost>

<VirtualHost something>
...
SetEnv vhostname vhost443
</VirtualHost>

Now restart the web server and try the request again. Check the access log for the destination IP address and the vhost name:

127.0.0.1 - - [26/Apr/2005:07:10:36 -0400] "GET /file.html HTTP/1.1" 200 1647 9.42.114.51 myhost.example.com MAIN
                                                                               |                 |            |
                                           IP address connected to by client---+                 |            |
                                           ServerName for selected vhost-------------------------+            |
                                           label for selected vhost-------------------------------------------+

Check if the vhost name logged (e.g., "MAIN") is the expected one. If an unexpected vhost name is logged, that would explain why your vhost-specific configuration is not applied to the processing of the request. The IP address and ServerName value which were logged can provide further hints.

Does IHS support byte range requests, and byte serving of PDF files?

Yes

What are the limitations of the MaxClients directive on Unix and Linux systems?

The Apache 1.3 documentation says "To configure more than 256 clients, you must edit the HARD_SERVER_LIMIT entry in httpd.h and recompile." This statement does not apply to IBM HTTP Server.

IBM HTTP Server 1.3.x has raised the built-in limit from 256 clients to 4096 clients.

IBM HTTP Server 2.0 and above is essentially limited by the amount of memory. You can configure up to 20,000 threads per child process, and configure up to 20,000 child processes, for an overall limit of 400,000,000. However, the address space of an individual child process may be exceeded with that many threads, and system memory may be exceeded with that many child processes.

What are the limitations of the ThreadLimit directive on Windows systems?

IBM HTTP Server 1.3.x on Windows has a built-in limit of 4096 threads.

IBM HTTP Server 2.0 and above on Windows has a built-in limit of 15,000 threads.

How can I recompile IBM HTTP Server?

A customer cannot recompile or relink IBM HTTP Server.

If instructions for a third-party module mention recompiling the web server for integration of the third-party module, consult with the provider of that third-party module to find out how to load it into the web server dynamically (using the LoadModule directive).

If the customer requires that they be able to recompile or relink the web server, we recommend using the Apache web server, for which a plug-in is provided by WebSphere. The Apache web server is not supported by IBM, but the customer will be able to use it with WebSphere Application Server using the WebSphere plug-in.

How can I use suexec with IBM HTTP Server?

example suexec implementation

Why does an extra slash appear in URLs sent to the origin (backend) server in reverse proxy?

For example, why does the origin server receive "http://www.example.com//index.html" as the URL?

The ProxyPass and ProxyPassReverse directives should have trailing slashes for the path and url arguments.

Bad example:

ProxyPass         /mirror/foo http://foo.com
ProxyPassReverse  /mirror/foo http://foo.com

Good example:

ProxyPass         /mirror/foo/ http://foo.com/
ProxyPassReverse  /mirror/foo/ http://foo.com/

Please explain the %D and %T access log formats.

What operations do these log formats measure?

These formats show the time to serve the request, from the time that the web server reads the first line of the request from the client to the time the web server processes the %D or %T format string while logging the results of the request. This logging (and resolution of %D/%T) occurs after WebSphere Application Server has written the entire response to the WebSphere Plugin, and the entire* response has been queued to the TCP layer by IHS (*:see Special considerations below).

%D formats the time in microseconds and %T formats the time in seconds. (%D is not available with IBM HTTP Server 1.3.)

Special considerations:

Differences in response time handling between IBM HTTP Server 1.3 and later releases

An example with two web servers connected by mod_proxy

The web browser connects to web server 1, which proxies the request to web server 2, which serves the request using any mechanism (WebSphere, CGI, static file, etc.).

  1. The web browser, directed by the user, starts connecting to web server 1.
    The connection is queued in the TCP layer of the web server 1 system until the handshake completes and a web server 1 thread is available.
  2. A thread in web server 1 accepts the connection and reads the first line of the request.
    At this point, web server 1 starts counting response time.
  3. Web server 1 reads the rest of the request, determines that the request should be proxied to web server 2, and starts connecting to web server 2.
    The connection is queued in the TCP layer of the web server 2 system until the handshake completes and a web server 2 thread is available.
  4. A thread in web server 2 accepts the connection and reads the first line of the request.
    At this point, web server 2 starts counting response time.
  5. Web server 2 performs the processing required to serve the request, such as forwarding the request to the WebSphere application server, running a CGI script, or serving a static page on the filesystem.
  6. Web server 2 generates and transfers all of the response to the TCP layer on web server 2, to be sent to web server 1.
    At this point, web server 2 stops counting response time. The access log record is written with the calculated response time.
    Because the client of web server 2 is an IBM HTTP Server proxy, we know that no request pipelining will occur, so web server 2's response time ends when it has transferred the last byte of the response to the TCP layer. Web server 1 may not have read all of the response for some time, however.
  7. As web server 1 reads response data, it transfers the data to the TCP layer for sending to the client.
  8. Web server 1 finally reads the last byte of the response from web server 2. Once the entire response has been read from web server 2:
    • If, prior to transferring the last piece of the response to the TCP layer on the web server 1 system, web server 1 determines that a subsequent request has already been received from the client, at this point web server 1 stops counting response time; the access log record is written with the calculated response time. The final byte of this response will be passed to the TCP layer once the first part of the subsequent response is passed to the TCP layer.
    • If no subsequent request has been received from the client, the last byte of the response will be transferred to the TCP layer immediately. At this point web server 1 stops counting response time. The access log record is written with the calculated response time.
  9. Finally, the client reads the last byte of the response from the TCP layer on its system. But the web server has already written its access log record (and thus calculated the response time).

What are common issues with custom HTTP (web) client software?

It is remarkably easy to implement a web client which can connect to web servers and send requests and read responses. But the simplest client may not work in all situations. Here are some problems we have seen:

response delimiters

There are several ways that the web server can tell the client when they've read the entire response:

end-of-connection
The end of TCP connection signifies the end of the response. This is signified by the lack of Content-Length: nnnn or Transfer-Encoding: chunked in the response header.
Any client must be able to handle this.
Content-Length
This is signified by the presence of Content-Length with a byte count in the response header. The client should read that many bytes from the TCP connection.
Any client must be able to handle this.
chunked transfer encoding
This is signified by the presence of Transfer-Encoding: chunked in the response header.
A client which cannot handle this form of response must specify HTTP level 1.0 in the request.

no handling dropped connections for requests sent in keepalive state

(If you don't know what this means, or your client does not handle this properly, ensure that the header field Connection: close is written in the request header.)

Keepalive state is a term for the state of the connection after a response has been received by the client. If the connection remains open after a response by consent of the client and server, the client has the opportunity to reuse the same connection for a subsequent request. Meanwhile, the server can drop the connection. So when the client sees a dropped connection instead of a response, it needs to start a new connection and issue the response again. Note: This is not appropriate when the client sees some part of the response.

If the client does not handle this, it must specify Connection: close in the request header.

lack of User-Agent header field in the request header

User-Agent identifies the type of software and level. It is always helpful for identifying the software which generated the request. It is sometimes helpful for tailoring the web server to act differently for a type of client software, or level. (Consider the BrowserMatch directive.)

sending TCP FIN packet before reading the response

The in-kernel cache handler for IBM HTTP Server on Windows does not support clients which send a FIN packet before the response is sent. Such clients must be modified to interoperate with this IBM HTTP Server feature.

How can I run more than one instance of IBM HTTP Server from the same installation directory?

Functional requirements

The function requirements vary based on the need of the different instances. You may wish to have different plug-in configuration files for the different instances (WebSpherePluginConfig), or serve different static files for the different instances (DocumentRoot). Different ports or IP addresses will be used for the different instances.

Operational requirements

The operational requirements are the configuration requirements that allow multiple web server instances to run from the same installation directory.

ports

A combination of listen port and listen IP address cannot be used by more than one instance.

For IBM HTTP Server 1.3, check the Port and Listen directives. For IBM HTTP Server 2.0 or higher, check the Listen directives.

log and other special files

Anything normally stored in the install_root/logs directory cannot be shared between instances. So each instance must have unique values for these directives:

  1. PidFile (applicable to all configurations)
  2. ScriptSock (applicable to non-Windows configurations of IBM HTTP Server 2.0 or higher with mod_cgid enabled)
  3. ErrorLog (applicable to all configurations)
  4. CustomLog or TransferLog (applicable to all configurations)
  5. SSLCachePortFilename (applicable to all non-Windows configurations with SSL enabled)

AIX: Can xlC.rte V7 be used?

IBM HTTP Server readmes and supporting software lists typically specify that xlC.rte 6.0 or higher must be used on AIX V5. xlC.rte V7 is upwardly compatible and can also be used. The specific V7 xlC.rte that has been tested with IBM HTTP Server is xlC.rte 7.0.0.1.

LoadModule order - When/why is it important?

LoadModule order in IBM HTTP Server 1.3

(ClearModuleList and AddModule also affect this. For the purposes of this discussion, an AddModule directive after the ClearModuleList directive is equivalent to LoadModule.)

The Apache 1.3 API allows modules to implement one or more hooks to perform initialization or request processing. Here are a few of the hooks which modules can implement:

Occasionally, there are requirements that one module's hook runs before another module's hook. This commonly occurs when the user has configured some module, such as the WebSphere plug-in, to process all requests, but they really want some of them to be processed by some other module, such as mod_rewrite. The Apache 1.3 API has no API to allow modules to declare when its hooks should run relative to the hooks of other modules. Instead, the order they run is determined by the LoadModule order. All hooks for modules loaded (or AddModule-d) later will run before the hooks of modules loaded earlier in httpd.conf.

For the common situation where mod_rewrite should take precedence over (run before) the WebSphere plug-in, mod_rewrite must be loaded or added after the WebSphere plug-in.

LoadModule order in IBM HTTP Server 2.0 and above

The Apache 2.0 API allows modules to implement one or more hooks to perform initialization or request processing. Here are a few of the hooks which modules can implement:

Occasionally, there are requirements that one module's hook runs before another module's hook. The Apache 2.0 module API allows modules to indicate, for each request processing phase, whether the module should be called first or last, or before or after another specific module. The hook order is defined separately for each hook. For example, a module could indicate that its transaction logger has to run before the transaction logger of other modules, and that its validate-user-id hook must run before that of mod_auth.

When modules don't have specific requirements, or when modules declare when they should run relative to other modules, the LoadModule order is not important. In fact, the LoadModule order can almost always be ignored with IBM HTTP Server 2.0 or above.

When modules have specific requirements for the order in which they run, but they fail to use the proper API to declare the required order to the web server, the user may be able to work-around problems by reversing the LoadModule order. There is no clear rule for the specific order of the LoadModule directives for module A and module B in order to make module A's hooks run before those of module B's. On some platforms the LoadModule for module A must come first; on other platforms, the LoadModule for module B must come first. There is no guarantee that reversing the LoadModule directives is a permanent change. If the system qsort() implementation in libc changes with system software maintenance or other changes are made to the configuration file, the LoadModule directive might have to be reversed again.

Questions which apply to IBM HTTP Server 2.0 and above

AIX: Why am I unable to unmount filesystem containing files served by IHS (affects HACMP environments)?

IHS 2.0 on AIX normally serves files using the send_file() API. This results in the files being stored in the AIX Network Buffer Cache. This leaves the files open as long as they are in the cache, preventing the underlying filesystem from being cleanly unmounted.

To clear files from the cache and unmount the filesystem:

What about MPM selection and prefork vs. worker?

IBM HTTP Server 2.0 and above uses the worker MPM on Unix and Linux systems, and it cannot be replaced. Any information about Apache that suggests recompiling the web server for a different MPM does not apply to IHS, as the MPM is pre-selected and IHS cannot be recompiled by customers.

In other words, the prefork MPM cannot be used with IBM HTTP Server.

What about mod_dir, mod_rewrite, and the WebSphere plug-in?

>We would like to know the priority of the following directives.         
>- mod_dir(dir_module)                                                   
>- mod_rewrite(rewrite_module)                                           
>- WebSpherePlugin(ibm_app_server_http_module)   

mod_dir only handles objects which can be served by IHS as static files, so it cannot be used to redirect requests to WebSphere. mod_dir has the lowest priority of these modules, and the priority cannot be changed. It will only try to handle a request if the request was for a directory and no other module has decided to serve the request.

With IHS 2.0, mod_rewrite always takes precedence over the WebSphere plug-in and, with the proper configuration, mod_rewrite can first rewrite URLs and then the WebSphere plug-in can see the rewritten URL and decide whether or not to serve it.

Example: Customer wants to use mod_rewrite to change URL /home to /servlet/home/, and customer has configured the WebSphere plug-in to handle /servlet/*.

Here is a mod_rewrite directive to map /home to /servlet/home, and at the same time pass it through to the WebSphere plug-in to allow it to see the rewritten URL. The PT flag on the RewriteRule is what allows the WebSphere plug-in to process the rewritten URL.

RewriteRule ^/home /servlet/home [PT]

Note: In IHS 1.3, the actual order of the LoadModule or AddModule directives also makes a difference. The LoadModule or AddModule for mod_rewrite needs to come after the WebSphere plug-in is activated to allow mod_rewrite to rewrite URLs and then have the WebSphere plug-in process the rewritten URL. This is not the case with IHS 2.0, where mod_rewrite always takes precedence.

Questions which apply to IBM HTTP Server 1.3.x

Where is mod_perl to work with IHS 1.3 on AIX?

mod_perl does not work with IHS 1.3 or normal Apache 1.3 on AIX. There is a build trick with Apache 1.3 to turn on run-time linking, which is required for proper mod_perl support. This involves building Apache 1.3 from scratch with special build flags to enable run-time linking.

Since IHS can't be rebuilt by the customer and IBM can't change the build of IHS due to customer migration concerns, customers need to use real Apache 1.3 with mod_perl. Information about how to build Apache 1.3 to use with mod_perl on AIX can be found on the web.

Why is POST data logged in access log as if it were a request?

A problem existed in all levels of IHS 1.3.x which allowed POST data to be treated as a request if a non-200 response was sent for the POST (e.g., 301 redirect, 401 authorization required, or anything else), and an ErrorDocument directive was present for that non-200 response or a third-party module had registered an error document. Make sure you have one of the following levels of IBM HTTP Server:

What are the recommendations for AcceptMutex with IHS 1.3 on AIX?

The accept mutex is necessary in multiple child process configurations to prevent the thundering herd problem, where multiple child processes wake up to handle a single incoming connection. The accept mutex is used to ensure that only one child process wakes up when an incoming connection is ready to process.

The accept mutex is always used when there is more than one listening socket. When there is a single listening socket, the accept mutex is used unless httpd -V (IHS 1.3) displays -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT.

The default for IHS 1.3.19 through IHS 1.3.26 on AIX is AcceptMutex pthread. This has the following problems with IHS 1.3:

  1. Idle child cleanup often doesn't work, as there is an incompatibility between the interface to pthread mutexes and the design of Apache 1.3's idle child cleanup. There is no work-around other than to switch the mutex mechanism to something else.
  2. There have been problems with third-party modules crashing in their child exit hook, and the child exit hook can sometimes be run while the process holds the pthread mutex. When this type of crash occurs, the server can hang. If fixes for the third-party module are not available, the mutex mechanism should be changed to something else. (This second issue has been sidestepped with Apache/IHS >= 1.3.28, as we have changed the code to release the accept mutex before running the child exit hook, in case the third-party module crashes there.)

    We have never seen this problem with IBM-provided modules (for example, the modules provided with IHS such as mod_rewrite, and the WebSphere plug-in module). If you are loading only IBM-provided modules into IHS (LoadModule directives in httpd.conf), then this is not a concern.

    If you are using non-IBM modules, we cannot predict in advance whether or not you will encounter this type of problem with that module. That depends on whether the exact version of that module has such a defect which can occur in your environment.

choosing the accept mutex mechanism on AIX

AcceptMutex pthread

This is the default mechanism for IHS 1.3.19 through IHS 1.3.26.x. This mechanism uses the pthread_mutex_lock() function in the AIX pthread library to serialize access to the listening socket between processes. The lock is in shared memory, which allows multiple httpd processes to use it. There is no underlying file associated with this type of mutex, so the LockFile directive is ignored.

pros

  1. high performance
  2. no system tuning required

cons

  1. mutex ownership not recovered if the mutex owner crashes
  2. with IHS 1.3, the pthread mutex mechanism can interfere with idle process cleanup
AcceptMutex sysvsem

This is a possible mechanism for IHS 1.3 (1.3.19.3 and above). This mechanism uses the semop() and semctl() functions in the AIX kernel to serialize access to the listening socket between processes. There is no underlying file associated with this type of mutex, so the LockFile directive is ignored. The semaphore is viewable with the AIX ipcs command.

pros

  1. high performance
  2. no system tuning required (internal AIX limits are sufficiently high)

cons

  1. A semaphore set will be lost if the parent process crashes. The semaphore set will have to be manually cleaned up by the administrator using the ipcrm command.
AcceptMutex fcntl

This is the default mechanism for IHS 1.3.12 and below and for IHS 1.3.28 and above. This uses the fcntl() kernel function to serialize access to the listening socket between processes. The httpd processes wait for exclusive access to a lock file, then they can safely access the listening socket(s). There is no real file I/O performed. Because the mutex is file-based, a lock file will be used. Normally, the lock file is stored in the logs directory under the IHS ServerRoot directory. The LockFile directive needs to be used in the following situations to override the default name of the lock file:

  1. IHS ServerRoot directory is on a network file system; use LockFile directive to place the lock file on a local directory
  2. multiple IHS instances share the same ServerRoot directory; use LockFile directive in each httpd.conf to specify different files (No operational problem would occur if the LockFile directive was missing; however, it could be confusing during problem diagnosis to see open files used by different IHS instances and see that they each are using lock files with the same name.)

pros

  1. no system tuning required
  2. widely used with Apache/IHS 1.3 on AIX, with no known problems

cons

  1. performance is slightly less than AcceptMutex pthread or AcceptMutex sysvsem; the actual difference is hard to measure with real world workloads

What format of text file userid/password is supported by IHS 1.3 on Windows?

The authentication module which handles flat files of userids and passwords is mod_auth (described in the IHS Infocenters or in the Apache 1.3 documentation). On Windows, mod_auth accepts flat text files of the form

userid:password

There are three allowable forms of the password:

  1. unencrypted (not recommended)
    Example:
    jeff:jeff
    
  2. MD5 hash, prefixed with the string "$apr1$"
    Example:
    jeff:$apr1$PN2.....$iPOw99RhtaeLLZ6OnXeGW/
    
  3. SHA1 hash, prefixed with the string "{SHA}"
    Example:
    jeff:{SHA}8+cx36KTx6gxGdiqz6QbXS14C+k=
    

The traditional "crypt" format of the password is not supported by IHS 1.3 on Windows.

apxs fails trying to access the regex library. How can this be corrected?

Example apxs failure with IBM HTTP Server 1.3.28 on AIX:

$ ihsinstall/bin/apxs -c -Wl,-bE:mod_test.exp mod_test.c
xlC_r -DAIX=433 -U__STR__ -DAIX_BIND_PROCESSOR -DUSE_HSREGEX -DUSE_EXPAT -I../lib/expat-lite -O2 -qcpluscmt   -DNO_DL_NEEDED -DSHARED_MODULE -I/home/trawick/testihs13build/ihsinstall/include  -c mod_test.c
ld -L../regex -lregex -H512 -T512 -bhalt:4 -bM:SRE -bnoentry -bI:/home/trawick/testihs13build/ihsinstall/libexec/httpd.exp -lc -o mod_test.so mod_test.o
ld: 0706-006 Cannot find or open library file: -l regex
        ld:open(): No such file or directory
apxs:Break: Command failed with rc=16711680

Note: The -Wl,-bE:mod_test.exp parameter is AIX-specific. In general, the supplier of the module should indicate if this or any other special apxs options are required for proper compilation.

To correct the problem, the apxs script in the IBM HTTP Server bin directory must be modified.

AIX example:

What public key lengths does ikeyman/mod_ibm_ssl support?

Why do I sometimes see 0 for the %D access log value on Windows?

IHS on Windows uses a system call to obtain two timestamps, one just after the request line is read and the second when the access log entry is made. Although the Operating System returns a value that has microsecond granularity, the timer is only updated once every OS timer tick, that is, 64 times per second. Thus if IHS processes a request in less than 15 milliseconds it is possible that 0 will be logged for the time taken to serve the request.

What restrictions are placed on ikeyman passwords?

Does IHS support DSA certificates?

IHS only supports RSA key exchange and RSA authentication. Ciphers using any of DSA authentication, or Diffie-Hellman / Ephemeral Diffie-Hellman are not supported.

The Java key management utility, keytool, will create DSA certificates by default, see the JSSE FAQ for more info.

How can I tell if mod_cache is working?

If you are logging the Request Handler you will see the request handler change from the content generator (mod_cgid, mod_proxy_http, mod_was_ap20_http, mod_core) to an empty value. Under some circumstances this will happen on the third, not the second, request for cacheable content.

Alternatively with LogLevel debug set, the following message is issued when mod_cache has served the request:     cache: serving /foo

Finally, if the "Age" header isn't being set by the content generator or some intermediate cache/proxy, the presence of the Age header in the response indicates that the file is being served from the cache. You can log the outgoing Age: header in the access log by adding %{Age}o to your LogFormat directive.

How does mod_cache interact with the WebSphere Plugin?

mod_cache can cache content generated by the WebSphere Plugin if it has the appropriate HTTP headers in the response, however this cache does not interact with the Plugin ESI cache. When mod_cache is cacheing content generated by the WebSphere Plugin you will not see evidence of the WebSphere Plugin being called for the cached request.

What content is cacheable?

See sections 13 of RFC2616, notably the presence of the E-Tag, Last-Modified, or Expires headers

How can proxy requests be authenticated?

Specify the authentication directives within a <Proxy > container. An example using file-based authentication follows:

LoadModule auth_module modules/mod_auth.so

<Proxy *>
AuthType Basic
AuthName "Restricted Files"

AuthUserFile /path-to-password-file

require valid-user
</Proxy>

The mod_proxy documentation contains a simpler example which allows access to the proxy based on the client IP address.

Can IHS be run in a chroot environment?

IHS running in a chroot environment is untested and unsupported. IHS support cannot assist with the configuration of such an environment and may require customer to reproduce defects in a traditional environment.

SSL Questions

How many SSL Session IDs can IHS cache?

See SSL Tuning

How can I log the TCP port a request was received on?

IHS cannot directly log the TCP port the request was received on. The %p LogFormat logs the port number specified in the ServerName or VirtualHost directive for the virtual host that handled the request. To have a meaningful differentiation via %p you should always a specify a VirtualHost for each listening port. Alternatively, when the directive UseCanonicalName is set to off, %p will prefer the port number provided by the client in the HTTP Host: header.

How can I require SSL client certificates (mutual SSL authentication) only on some URLs in a VirtualHost?

This cannot be easily accomplished because there is no support for telling the web browser to "try again with a client certificate." The following recipe is one way to simulate this behavior without using an additional virtual host, which would involve redirecting select URLs to the alternate virtual host.

  1. Set SSLClientAuth optional in your virtual host
  2. Use mod_rewrite to check one of the SSL client certificate environment variables:
    RewriteEngine on
    RewriteCond %{ENV:SSL_CLIENT_CERTBODYLEN} ^$
    RewriteRule /secure/ /certrequired.html
    
  3. Provide an HTML page (/certrequired.html in the previous step) describing what your users need to do get a certificate. Note that users would probably have to close and reopen their web browser before they'd be able to select a client certificate, which can only happen at the beginning of a new handshake.

Why must IP-based virtual hosting be used when multiple SSL virtual hosts are supported?

This technote describes the configuration requirements:

Why?

A TLS extension has been defined in RFC 3546 which allows selection of the virtual host during the handshake, avoiding this dependence on IP addresses. In the coming years we'll see browsers which are able to support this TLS extension, but it will be a very long time before an customers could rely on that because older browsers would be unable to participate.

Note: It is the IP address/port combination which must be unique. You could support multiple SSL-enabled virtual hosts on the same IP address if they differ in port number, but that would require that clients specify the port number in https URLs for all but one of the SSL-enabled virtual hosts.

How can I disable support for NULL / Plaintext ciphers?

Specifying any SSLv3/TLSv1 ciphers as illustrated in the performance guide will disable support for the NULL/Plaintext ciphers, provided you don't explicitly enumerate the following ciphers:

SSL_RSA_WITH_NULL_SHA
SSL_RSA_WITH_NULL_MD5
SSL_NULL_WITH_NULL_NULL
Note: The following releases disable NULL ciphers by default:

How can I disable support for SSLv2?

Use the SSLCipherSpec directive and configure support for only SSLv3 and TLSv1 ciphers, as in the following example:

# This first cipher spec is CPU-intensive.  You may want to
# comment it out, if the other forms of encryption are
# sufficient.
SSLCipherSpec SSL_RSA_WITH_3DES_EDE_CBC_SHA
SSLCipherSpec SSL_RSA_WITH_RC4_128_SHA
SSLCipherSpec SSL_RSA_WITH_RC4_128_MD5
SSLCipherSpec SSL_RSA_WITH_DES_CBC_SHA
SSLCipherSpec TLS_RSA_EXPORT1024_WITH_RC4_56_SHA
SSLCipherSpec TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA
# If 40-bit encryption is sufficient, uncomment these last two.
# SSLCipherSpec SSL_RSA_EXPORT_WITH_RC4_40_MD5
# SSLCipherSpec SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
Note: The following releases support the SSLProtocolDisable directive to accomplish this more directly

Place these directives inside the <VirtualHost > containers which contain SSLEnable. More Information

How can the other SSL access control directives be used to limit access?

Per-directory SSL access control directives

Unfortunately, the restrictions configured with SSLCipherBan, SSLCipherRequire, and SSLVersion do not influence the actual SSL handshake and are only checked later on during request processing. No SSL renegotiation is triggered by these directives, and instead the configured 403 error response is issued at the application level. This 403 response may be difficult to distinguish from 403 errors triggered by other authorization or access control directives.

As an example of why SSLVersion is difficult to implement, if you use SSLVersion SSLv3 (or SSLv2) and a browser connects with a "stronger" protocol, not only do they get a generic 403 response but the user would have to take some action to disable the stronger/preferred SSL protocols in their browser to be able to reconnect. Using SSLVersion TLSv1, which requires the latest SSL protocol, sends clients without TLSv1 support a generic 403 response. This 403 response can be customized with the ErrorDocument directive but it is not distinguishable from other access control errors in the same context.

Because of the limitations of SSLCipherBan, SSLCipherRequire, and SSLVersion, using mod_rewrite to analyze the SSL environment variables (HTTPS_CIPHER, SSL_PROTOCOL_VERSION, HTTPS_KEYSIZE) is much more flexible.

per-vhost SSL handshake directives

SSLCipherSpec and SSLProtocolDisable influence the SSL handshake itself, and as a consequence are only available in a per-vhost basis. While it's normally safe to limit cipher support to "128-bit or higher ciphers" or to disable SSLv2, we do not recommend restricting access much further than this with SSLCipherSpec and SSLProtocolDisable. Instead, use mod_rewrite as illustrated above to enforce more restrictive access control; otherwise IHS and the browser may not be able to negotiate a secure channel and users may not see a descriptive error message from their browser.

How can I display a custom document when a client connects over SSLv2?

Instead of using mod_ibm_ssl SSLCipherSpec directives to allow only SSLv3 and TLSv1 ciphers, use mod_rewrite to recognize when SSLv2 is used, and redirect the request to a document explaining the restriction.

Example:

RewriteEngine On
RewriteCond %{ENV:SSL_PROTOCOL_VERSION} ^SSLV2$
RewriteRule .* /low_grade_encryption.html

How can I display a custom document when a client connects with a weak cipher?

RewriteEngine On
RewriteCond %{ENV:HTTPS_KEYSIZE} !^(128|168|256)$
RewriteRule ^/secret3/ /128_or_higher.html

How can I apply other rules based on attributes of SSL ciphers?

RewriteEngine On
RewriteCond %{ENV:HTTPS_CIPHER} !AES
RewriteRule ^/secret1/  /AES_only.html

RewriteCond %{ENV:HTTPS_CIPHER} MD5
RewriteRule ^/secret2/  /no_md5.html

What is a substitute for mod_ssl's SSLRequireSSL directive?

The SSLRequireSSL directive is not supported with any level of IHS. IHS uses a different SSL implementation than available for Apache 1.3 or Apache 2.0.

Instead of using the SSLRequireSSL directive to specify that certain files or directories can only be served over SSL, a customer can achieve the same result in different manner, by denying access to the file or directory in the non-SSL configuration. In following example, files under URI /onlyssl can only be served over SSL:

...                                                                     
# /onlyssl can't be served by default
<Location /onlyssl>                                                     
 Order Allow,Deny                                                       
 Deny from all                                                          
</Location>                                                             
...                                                                     
<VirtualHost *:443>                                                     
SSLEnable                                                               
...                                                                     
# put this config for /onlyssl inside all SSL-enabled                   
# VirtualHost containers                                                
<Location /onlyssl>                                                     
  Order Allow,Deny                                                      
  Allow from all                                                        
</Location>                                                             
</VirtualHost> 
...

How can I see which cipher specification was negotiated for a specific request?

in access log

  1. Change the LogFormat directive to include the cipher specification as part of the information logged for each request. The format string %{HTTPS_CIPHER}e will log the name of the cipher (e.g, TLS_RSA_WITH_AES_256_CBC_SHA). Ensure that the LogFormat directive which is changed is for the format used on the CustomLog directive.

    Example:

    LogFormat "%h %l %u %t \"%r\" %>s %b %{HTTPS_CIPHER}e" common 
    CustomLog logs/access_log common 
    
  2. Look in the access log to find the cipher used. The position of the cipher will depend on where the %{HTTPS_CIPHER}e format string was placed in the LogFormat directive. Using the example LogFormat directive above, here are example access_log entries:
    9.48.108.152 - - [17/Feb/2005:15:37:39 -0500] "GET / HTTP/1.1" 200 1507 SSL_RSA_WITH_RC4_128_SHA 
    9.48.108.152 - - [17/Feb/2005:15:37:40 -0500] "GET /httpTech.view1.gif HTTP/1.1" 200 1814 SSL_RSA_WITH_RC4_128_SHA
    9.48.108.152 - - [17/Feb/2005:15:37:40 -0500] "GET /httpTech.masthead.gif HTTP/1.1" 200 11844 SSL_RSA_WITH_RC4_128_SHA 
    9.48.108.152 - - [17/Feb/2005:15:37:41 -0500] "GET /httpTech.visit1.gif HTTP/1.1" 200 1457 SSL_RSA_WITH_RC4_128_SHA 
    

    For non-secure requests, "-" will be logged for the cipher specification.

The key size can be logged with the %{HTTPS_KEYSIZE}e format string. See the section on SSL environment variables in the IBM HTTP Server InfoCenter for information about other SSL environment variables which can be logged. See the documentation for the LogFormat and CustomLog directives for more information about format strings in general.

with Ethereal

A manual way to check this is to use Ethereal on the client system and start a packet trace capture. Then load the web page with your choice of web browser. Then stop the capture in Ethereal and look for the Server "Hello" response. This will appear in the packet window like this:

  1.750088  server-ip-address client-ip-address TLS   Server Hello, Certificate, [Unreassembled Packet]

Select that packet, then look for the "Handshake Protocol" information in the next window:

    Handshake Protocol: Server Hello
        Handshake Type: Server Hello (2)
        Length: 70
        Version: TLS 1.0 (0x0301)
        Random.gmt_unix_time: Apr  8, 2005 14:15:33.00000000
        Random.bytes
        Session ID Length: 32
        Session ID (32 bytes)
        Cipher Suite: TLS_RSA_WITH_RC4_128_MD5 (0x0004)
        Compression Method: null (0)

Check the display of the cipher suite.

Consult the Ethereal documentation for further information about using that tool.

with openssl command-line client

If you have the openssl command-line client (not part of IHS, but distributed at www.openssl.org), that can display the cipher used as well, for an SSL session established by that command-line client.

To see which cipher is selected for the request, run openssl s_client -connect IPADDR:PORT and look for this part of the output:

New, TLSv1/SSLv3, Cipher is AES256-SHA

The symbolic names for the ciphers as displayed by openssl are are not the same symbolic names used by IHS. Here are the openssl names for common ciphers used with IHS:

IHS name OpenSSL name
TLS_RSA_WITH_AES_256_CBC_SHA AES256-SHA
TLS_RSA_WITH_AES_128_CBC_SHA AES128-SHA
SSL_RSA_WITH_RC4_128_SHA RC4-SHA
SSL_RSA_WITH_RC4_128_MD5 RC4-MD5
TLS_RSA_EXPORT1024_WITH_RC4_56_SHA EXP1024-DES-CBC-SHA
TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA EXP1024-RC4-SHA
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 EXP-RC2-CBC-MD5
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 EXP-RC2-CBC-MD5
SSL_RSA_EXPORT_WITH_RC4_40_MD5 EXP-RC4-MD5

The openssl client supports many ciphers which are not supported by IHS.

openssl will hold the connection open until you interrupt it with the EOF character (usually <Ctrl>D on Unix systems).

You can restrict the openssl client to a particular cipher to see if IHS supports it, using the -cipher CIPHERNAME option.

Consult the OpenSSL documentation for further information about using the openssl command-line tool.

How does IHS use the close_notify SSL alert?

IHS does not initiate a close_notify alert during the shutdown of a connection, but will respond to a client's close_notify with one of its own. This behavior is not configurable.