Hack 57 Metabase Hacks


with IIS, but you can do them only by editing the metabase.These are a few of my favorite IIS metabase
hacks. You can find lots more informationtoo much,
perhapsin the IIS SDK's IIS Metabase
Properties Reference on MSDN (http://msdn.microsoft.com/library/en-us/iisref/htm/reference.asp).
Most of the information there is pretty dry stufflists of
different settings that provide little insight into what might be
useful to tweakwhich is why I want to start you off with a few
interesting hacks to inspire you. Still, it is a good idea to get
familiar with how to read the Reference, because it details the
allowable values for each property in the metabase.Except where stated otherwise, all of the following hacks work on
both IIS 5 and IIS 6, though the effect in some cases might differ
depending on the rest of your IIS configuration; I try to make note
of such differences when appropriate. Also, most of these properties
require IIS to be restarted before they take effectsomething
that's usually a good idea anyway whenever you edit
the metabase manually. Even on IIS 6, which lets you edit the
metabase while IIS services are running, it's often
a good idea to use the iisreset command to stop
and start IIS after making metabase changes and see if there is any
effect.
A Warning Before Hacking the MetabaseBefore you start hacking the metabase, remember that editing the metabase (like editing the Registry) shouldn't be done lightly; the preferred method is to configure IIS using the Internet Services Manager GUI tool. Unfortunately, a number of useful metabase settings are inaccessible from the GUI and you have to dig right into the metabase to change them.Also, before you edit the metabase make sure you back it up. That way, if you make a mistake and break IIS, you can restore the metabase from backup and get IIS working again. We looked at ways you can back up the metabase [Hack #54] earlier in this chapter, but it's also a good idea to make a copy of the metabase and edit the copy instead of editing the metabase itself. Then, when you've made your changes, you can stop IIS, rename metabase.bin to metabase.old, rename your copy of the metabase from whatever you called it to metabase.bin, and restart IIS. Should something go wrong, your original metabase is still there in the form of metabase.old and can be used to restore IIS to the configuration it had previously. That may sound like overkill, but you can never be too careful when it comes to manually editing critical configuration files. You should at least follow that procedure with IIS 5 (Windows 2000). With IIS 6 (Windows Server 2003), you can probably get by without following this approach, because the history feature saves a copy of the metabase every time you make a configuration change to it. You decide, though. Like most things in IT, it's a tradeoff, and in this case, the tradeoff is between convenience and safety. Making backups of backups is not convenient, but it might help prevent you from burning your fingers.Also remember that MetaEdit (the downloadable tool for editing the IIS 5 metabase) doesn't check your modifications to ensure that the values you entered are within the allowable range for the properties you edit. Editing the IIS 6 metabase using Notepad or some other text editor is even more dangerous, because you could even assign a string value to a metabase property that should be numeric. So, before you change any metabase property manually, check the Reference to see which range of values is allowed. |
ServerListenBacklog
Sometimes, IIS cracks under the weight of too
many client requests, even though it still has lots of memory and CPU
cycles to work with. Typically, clients start getting
"Server too Busy" errors and have
to click Refresh several times before they are able to see any
content. At the server end, this might happen on only one IP address,
and any others might behave as they should. With a packet-sniffing
tool such as the Microsoft Systems Management
Server's Network Monitor, you'll
see TCP connections resetting almost as soon as they are established.
The problem is that the application layer of the TCP/IP stack has run
out of resources. To increase the resources available for this layer,
you can edit two metabase properties:
ServerListenBacklog and
MaxEndPointConnections (we will discuss the latter
in the next section).The ServerListenBacklog property determines the
maximum number of outstanding TCP socket connections that can be
queued. By default, this property is set in the metabase schema and
depends on how the Performance Tuning setting is configured on the
Performance tab of your web server's properties
sheet in the GUI. Specifically,
ServerListenBacklog has defaults of
5, 40, or
100, depending on whether you tune the GUI to
expect fewer than 10,000 hits per day, less than 100,000 hits per
day, or more than 100,000 hits per day. You can override the schema
defaults for this property by adding a
ServerListenBacklog key at the web
site's level (/LM/W3SVC) or at
the level of an individual web site, such as the Default Web Site
(/LM/W3SVC/1); assign the
ServerListenBacklog key any value from
5 to 1000 (on IIS 5) or
500 (on IIS 6). More pending connections are
queued as you increase the value for this key, but IIS will consume
more memory resources. Experiment to find the best performance for
your hardware.
MaxEndPointConnections
Another property you can tweak to
improve performance under heavy load is
MaxEndPointConnections, which indicates the
maximum number of TCP sockets in a LISTENING state that can be
allowed for a single IP address, network interface, or TCP port. By
default, this property has the value 100 on IIS 5
and is also set in the schema, but you can add a key to set it at the
/LM/W3SCV level or the
/LM/W3SVC/n level,
where n is the site ID of the web site
that contains the application. To get better performance under heavy
load, try increasing this setting to 500 or even
higher and evaluate the result from the client standpoint. On IIS 5,
MaxEndPointConnections works in conjunction with
ServerListenBacklog and IIS uses the property with
the lower value by default. On IIS 6, however,
MaxEndPointConnections is set to
4294967295 in the schema, which means unlimited
connections and is usually best left as is.
AspThreadGateEnabled
Thread gating is a feature of IIS
that is turned off by default, but if you turn
it on, IIS dynamically adjusts the number of concurrent threads,
depending on the load. If threads become blocked (for example, when
an ASP application on IIS has to wait for a back-end SQL database to
respond), then IIS starts more threads to handle client requests. If
processor usage hits the wall, IIS begins decommissioning threads to
reduce the amount of context switching going on. The lower- and
upper-level CPU usages that start or kill threads are determined by
two other metabase properties:
AspThreadGateLoadLow and
AspThreadGateLoadHigh. By default, these
properties have values of 50 and
80 (percent), respectively, but you can change
them to see if it improves performance.I've sometimes found that changing
AspThreadGateEnabled from off
(0) to on (1) can improve
performance somewhat for web servers that host mainly static content.
For servers that host ASP applications, use the Performance console
first to check if ASP requests are becoming excessively queued. If
so, try changing AspThreadGateEnabled to
1 and use Performance again to see if things
improve.This key is already present in the metabase at the
/LM/W3SCV level, but you can also set it at the
/LM/W3SVC/n level by
creating the appropriate key. Note that this particular metabase
property applies only to IIS 5, not IIS 6.
AspProcessorThreadMax
The AspProcessorThreadMax property
determines the maximum number of worker
threads IIS allows for handling ASP requests. The default value is
25 (threads per processor), and if you multiply
the number of processors on your machine by the value of
AspProcessorThreadMax, the product represents the
maximum number of threads that can service a single ASP
applicationregardless of how you have tweaked the previously
described AspThreadGateLoadHigh property. In some
cases, you might want to try increasing this valuefor example,
when ASP requests are being blocked by slow response from a back-end
database. In other cases, decreasing it to 15 or
even 5 might improve performance by better
utilizing available processor resources, especially under relatively
light loads. Basically, just play with it and see what happens. This
property is defined at the /LM/W3SCV level, but
you can also set it at the
/LM/W3SVC/n level.
AspAllowSessionState
The AspAllowSessionState property
enables session state persistence for ASP
applications and is set to 1 (on) by default. One
way you can often improve ASP performance is to change this property
to 0 (off) and then recode your applications to
explicitly override session state persistence for pages that use
session objects. Simply add the following statement to the top of
each ASP page as needed:
<% @EnableSessionState=False %>
This property is defined at the /LM/W3SCV level,
but you can also set it at the
/LM/W3SVC/n level.
AspBufferingOn
Big improvements in ASP performance can
often be achieved by turning ASP buffering
on using the AspBufferingOn property. This is
because ASP buffering lets IIS collect the output of an ASP
application in a buffer before flushing it to the client.
Fortunately, this property is set to 1 (on) in
IIS, provided you're working with a clean
installation of Windows 2000 or Windows Server 2003. If you
previously upgraded your web server from Windows NT 4.0, however,
this property is set to 0 (off) and should
generally be changed to 1, at least on all your
production servers. However, while turning this property on increases
ASP response times overall, from a user perspective it might actually
seem to make sites less responsive. This is because instead of
feeding the output of the ASP page to the user slowly, bit by bit,
the entire output has to be generated and cached before any of it can
be returned to the user. So, you'll have to play
with this and see what how it feels from a client perspective, but in
most cases it's best left turned on. You can also
recode your ASP applications to make more use of the
Response.Flush method to improve the performance
from the user's point of view. This property is
defined at the /LM/W3SCV level, but you can also
set it at the
/LM/W3SVC/n level.
AspQueueConnectionTestTime
Ever tried to access a page that wouldn't
load, so you kept refreshing impatiently?
On the older IIS 4 platform, this had the unpleasant result of
filling up the ASP request queue with multiple requests from the same
user for the same page, which was quite annoying. Fortunately, in IIS
5 the AspQueueConnectionTestTime metabase property
was added to foil this kind of unintentional denial-of-service attack
on your web server. The default value for this key is
3 (seconds), but you can tweak it depending on how
your ASP application is designed. For example, if you have an
application in which the user usually just clicks through a number of
pages without needing to fill in or read anything, you could add this
key to the /LM/W3SVC/n
level for that site and lower its value to 2 or
even 1. That way, IIS will check more frequently
to make sure the client is still connected before responding to
another connection request from the same client. This property is
defined at the /LM/W3SCV level, but you can also
set it at the
/LM/W3SVC/n level.
AspScriptFileCacheSize
The AspScriptFileCacheSize property
determines how many precompiled script
files or templates are cached in memory by IIS, in case they need to
be reused. The default value for this setting is
250 (in IIS 5) or 500 (in IIS
6), but this can be increased to 1000 or more if
needed. You can also set it to -1 (on IIS 5) or
4294967295 (on IIS 6) to allow unlimited caching
of scripts. Unlimited caching is probably not a good idea unless you
have unlimited RAM on your motherboard, but you definitely might
consider increasing this setting to 1000 or higher
if your server is running applications that have many different ASP
pages. This property is defined at the /LM/W3SCV
level, but you can also set it at the
/LM/W3SVC/n level.
CacheISAPI
The CacheISAPI property determines
whether IIS caches ISAPI extensions (such
as asp.dll) in memory or unloads them whenever
they're no longer used. This is set to
1 (on) and should be left that way on production
servers, unless you want your applications to run like molasses.
However, if you need to debug a custom ISAPI extension
you've written, set CacheISAPI to
0 (off); otherwise, you'll end up
testing previous versions of your extension instead of testing the
current one. This property is defined at the
/LM/W3SCV level, but you can also set it at the
/LM/W3SVC/n level.
ID 36907
I'll end this list of hacks with something a little
bit different. Until now, we've looked only at
metabase properties for IIS proper. However, some other Microsoft
products also use IIS; one of the most notable is Exchange 2000
Server. Every metabase property is uniquely identified by an internal
ID number. For example, the CacheISAPI property
has ID number 6034, which can easily be seen using
MetaEdit (see Figure 6-5).
Figure 6-5. Viewing the CacheISAPI property in MetaEdit

It's a little-known fact that these ID numbers are
grouped into different ranges that depend on the IIS function to
which they apply (IIS, ASP, or FrontPage) or the Microsoft server
product to which they belong (such as Exchange Server or Application
Center). Table 6-1 details the association between
metabase Ids and their associated functions or products.
ID range | Function/Product |
---|---|
1-32767 | IIS |
28672-32767 | ASP (subset) |
32768-36863 | FrontPage Server Extensions |
36864-40959 | Exchange Server: SMTP |
40960-45055 | Exchange Server: POP3 |
45056-49151 | Exchange Server: NNTP |
49152-53247 | Exchange Server: IMAP4 |
53248-57343 | MSCS |
57344-61439 | Application Center |
Exchange's SMTP Service and can be used to change
the default SMTP banner with which Exchange responds to incoming
client connections. Changing the property's banner
from its defaultESMTP MAIL Service, Version:
5.0.2195.1600 (or something similar)is a useful
security measure, because it hides Exchange from unauthorized Telnet
connection attempts issued by attackers who are trying to footprint
your system.To change the banner for property 36907, open
MetaEdit and find
/LM/Smtpsvc/n, where
n is the number of the SMTP virtual server
used by Exchange. Then, select
Edit
open the Edit Metabase Data dialog box (shown in Figure 6-6).
Figure 6-6. Adding a new property to the metabase based on its internal ID number

Since the Id drop-down box lists only standard IIS metabase
properties, you have to add this property using its ID number
instead. Leave the list box set to (Other) and type
36907 in the box beside it. Then, in the Data text
box, type the banner you want the SMTP Service to display to
clientsperhaps something like "Stop trying to
footprint my server!" Finally, stop and restart the
SMTP Service on your machine. Now, when a Telnet client tries to
connect on port 25, he'll get the message you
specified. Of course, you might not want to use that particular
message; it might only annoy the attacker and make her even more
determined to crack your system!By the way, you can do the same thing with your POP3 connection and
disconnection strings (IDs 41661 and
41662, respectively) and your IMAP4 connection and
disconnection strings (IDs 49884 and
49885, respectively). Be sure to restart these
services once you modify their metabase settings.