[Maarten Van Horenbeeck] [Information Security] [Resources]
Migrating from Apache/IIS to Publicfile
Publicfile is a webserver created by Dan Bernstein. It supports only a very limited subset of the Apache functionality, but this makes it likely that it is in fact quite secure. When you are migrating a site from Apache to Publicfile, there are some issues you will experience. One word of caution: if you are using any functionality included in any Apache modules, do not migrate. These will not work.
When you perform the migration, there is also a set of Apache built-in functionality which is not available on Publicfile:
- Combined/Common logging: Publicfile uses a very unique style of logging. If you want Combined or Common logging, you will need to acquire the patch written by Tivano Software gmbh. Get it here.
When you have installed the patch, you will need to make an (undocumented) change to the run
file of your HTP setup. This will need to include the following line, to make sure the httpd_log_combined (or httpd_log_common) environment variable is set when the daemon is executed:
export HTTPD_LOG_COMBINED=1
Add this before the exec 2>&1
When this is done, Apache style combined_logs will be stored in the current
logfile as well whenever a request is made. You can easily grep out the Apache logs with the following command:
cat current | grep "\[" | cut -d " " -f 2-
This will drop the Publicfile timestamp, and take everything from there if it's in the combined_logging format.
- Directory access: When a file is requested which does not exist, Apache verifies whether a directory exists with that name. If it does, it will send a 301 Permanently Moved back to the client, redirecting him to that directory (by adding a trailing slash to the initial request). This is not supported by publicfile, but Giles Lean wrote a patch that is difficult to find on the net nowadays. Therefore we mirror it here.
- The list of MIME types included by default in Publicfile is very limited. This can give issues if you are making certain files available for download. The client may not receive a correct MIME type, and as such may not understand how to interpret the file. For example: .jpeg files are recognized as JPEG, but .jpg files are not. A patch for this purpose is available from Uwe Ohse here. This patch allows publicfile to guess the MIME type of a file through its extension.
- Downloads: Publicfile does not support the basic feature of byte ranges. This makes that certain clients, most noticeably curl, will not be able to download from it. A patch, written by Andreas Kotes can be found here. Please do read the full thread on this patch - a number of issues with it have been identified in a follow-up e-mail. Thanks to Peter Conrad for bringing this to my attention.
After you make the move, you might receive reports from users getting an error message "I do not accept If-None-Match". This is typical for certain Internet Explorer clients in combination with an ex-Apache site.
When you connect to an Apache site, the daemon will send through an ETag: header, a little bit like this:
Last-Modified: Sat, 21 Jan 2006 22:45:03 GMT
ETag: "548123-1953-43d2b96f"
RFC2616 describes this ETag as being offered to the client to allow him to compare it with other entities from the same resource. Simply put, it allows the client to state which version of the document it already has, to save bandwidth from being used on content that has already been transferred.
Not many clients actually use this, but when they do (as is the case with IE 6.0 on Windows XP), they will use the "If-None-Match" tag to indicate which version they already have cached.
When Publicfile sees this header in a request, it discards the request and barf()s an error message. While in essence, this does not matter if it is a new site, you will run into trouble if you are moving from Apache. Older clients will be running into difficulties and may not be able to access your site without clearing cache, deleting locally stored files and so on.
A quick fix to resolve this is to comment out the following two lines in httpd.c:
if (case_startb(field.s,field.len,"if-none-match:"))
barf("412 ","I do not accept If-None-Match");
After recompiling and reinstalling the binaries, everything should be working. You may wish to go back to a clean installation after a week or two, when most client caches will be outdated and cleaned.