Configuration extensions are extensions to the configuration system.
The configuration system is at the core of the IIS 7.0 administration
stack. Its primary purpose is to provide an interface to reading and
writing IIS configuration, which is consumed by Web server run time and
modules, and which is managed through the tools and APIs in the
administration stack. The configuration data itself is stored in a
hierarchy of XML files and is broken up into units called configuration
sections.
Each configuration section is an XML element that
can contain attributes, subelements, and collections of child elements
that describe the configuration data for the section. This data can be
specified at multiple locations in the configuration file hierarchy to
specify configuration settings for a particular configuration path. For
example, the following configuration for the <defaultDocument>
section placed in an application’s Web.config file adds Index.php as an
eligible default document and enables the default document feature for
that application:
<configuration>
<system.webServer>
<defaultDocument enabled="true">
<files>
<add value="index.php" />
</files>
</defaultDocument>
</system.webServer>
</configuration>
Typically,
each Web server module has its own section, and the Web server core
itself defines a number of sections such the <sites>,
<applicationPools>, and <serverRuntime> sections. The
configuration section is the basic unit of extensibility for the
configuration system, giving custom Web server features the ability to
provide their own configuration sections in the same way that IIS 7.0
features do.
Unlike the ASP.NET configuration system,
which relies on .NET classes implementing the
System.Configuration.Section base class to understand the contents of
each configuration section, the IIS configuration system is declarative.
Each configuration section is defined by registering its schema on the
server, which enables the configuration system to process the
configuration data for this section. By manipulating the schema, you can
add new configuration sections to the system, remove existing ones, or
extend existing configuration sections to contain more functionality.
Next,
we will look at the configuration schema mechanism in detail and see
how it can be used to add custom configuration sections.
Configuration Section Schema
The configuration section schema definitions are stored in XML files located in the %windir%\System32\Inetsrv\Config\Schema directory. After installation, IIS 7.0 contains the following schema files:
-
IIS_schema.xml. Defines all of the IIS configuration sections
-
ASPNET_schema.xml. Defines all of the ASP.NET configuration sections declared in Framework Root.config
-
FX_schema.xml. Defines all of the .NET Framework configuration sections declared in Machine.config
-
rscaext.xml. Defines
administration extensions to the IIS <sites> and
<applicationPools> configuration sections to expose run-time state
information and control APIs.
Caution
Never attempt to modify any of the built-in
IIS schema files. You can add new schema to define new configuration
sections and even add dynamic functionality to existing configuration
sections by publishing new schema files.
These files define the schema for the
configuration sections used by IIS and its features, which expect these
configuration sections to be in a specific format. These files are not
intended to be modified except by Windows Setup, and therefore they are
protected to be writable by TrustedInstaller only. This also means that
it is not necessary to back up these schema files, because they are
protected and can be restored from Setup (although you should back up
custom schema files).
The IIS 7.0 configuration system is not used by
ASP.NET or other .NET Framework programs to read the contents of .NET
Framework and ASP.NET configuration sections specified in the Framework
Machine.config and root Web.config files. The .NET and ASP.NET programs
use the .NET configuration system (developed by the ASP.NET team) to
read that configuration. So, you may wonder why the IIS configuration
system provides schema information for those configuration sections. It
is to allow the rich IIS 7.0 administration stack to manage ASP.NET
configuration so that Administrators can manage the entirety of server
configuration with a single set of tools and APIs. Although ASP.NET
provides its own API for managing .NET configuration (System.Configuration.dll),
it does not support IIS configuration and does not provide the same
level of tool and automation support provided by the IIS 7.0
administration stack.
However, the IIS schema files are provided
for .NET Framework 2.0 only and, because of configuration changes, may
not work correctly when used for other versions of .NET Framework. The
IIS team may provide a versioning solution for .NET configuration schema
in the future, but it is not there in IIS 7.0. Moreover, some tools in
the IIS administration stack (including the Appcmd command-line tool)
hardcode v2.0.50727 of the .NET Framework when working with
configuration in Machine.config and root Web.config files, so they
cannot be used to edit machine-level configuration for other .NET
Framework versions.
Here is an example of how the <defaultDocument> configuration section for the Default Document feature is defined inside IIS_schema.xml:
<sectionSchema name="system.webServer/defaultDocument">
<attribute name="enabled" type="bool" defaultValue="true"/>
<element name="files">
<collection addElement="add" clearElement="clear" removeElement="remove" mergeAppend="false">
<attribute name="value" type="string" isUniqueKey="true"/>
</collection>
</element>
</sectionSchema>
The schema definition specifies each
attribute and defines what child elements and element collections can be
contained within the section. In addition to defining the XML
structure, the schema definition also provides various metadata for
attributes, child elements, and collections that control the behavior of
the configuration system with respect to the section. For example, it
specifies that the type of the enabled attribute is Boolean, that its default value is true, and that the value attribute of the collection element is the collection key.
The IIS_schema.xml
file, arguably the main schema file, contains the description of the
schema information that can be specified for each section. For each
section, this information can contain the items listed in Table 1.
Table 1. Schema Elements
Schema Element |
Description |
---|
<sectionSchema> element |
Contains all of the schema information for a
configuration section, as well as the fully qualified name (containing
the section group path and the section name) for the section. |
<attribute> element |
Defines an attribute that can be used in the
configuration section or its child elements. It specifies the name, data
type, and other applicable information including default value, whether
it is required, whether it should be encrypted, and validation
information. |
<element> element |
Defines a child element, which can specify additional attributes, as well as other child elements and collections. |
<collection> element |
Defines a configuration collection, which can
contain a list of elements that can be indexed via attributes marked as
collection keys. Also supports various collection semantics such as
ordered lists and hierarchical merging of elements. |
Each of these elements supports a number of
schema properties that control the specific behavior of the
configuration system with respect to the configuration section being
defined. For more details on using these properties to specify the
behavior of your configuration section, refer to the comments in the
IIS_Schema.xml configuration file.
Note
The schema files are local to the server. If
you are using a shared configuration to host ApplicationHost.config on a
network share, you must make sure that the required schema files are
installed on each server that references the configuration file. Servers
that do not have the required schema files will not be able to read the
custom configuration sections for which they are missing the schema
information. This is only needed for schema files that are not part of
IIS 7.0 by default, because the latter are always installed when IIS is
installed.
By including additional XML files containing
section schema, you can add new configuration sections or extend
existing ones to contain more configuration information or expose
additional administration functionality. Before new configuration
sections can be used in the configuration files, they must also be
declared. We’ll look at this next.
Caution
Never attempt to delete or modify the schema
files that are included with IIS 7.0 installation. Unlike the modules,
most of these schema components are installed with the base IIS 7.0
installation, and their removal may break core pieces of the system that
expect the configuration sections defined therein to be available.
Likewise, you should not modify the schema of built-in IIS 7.0
configuration sections, because core components rely on their specific
structure. This is one of the reasons these schema files have a
TrustedInstaller-only access control list (ACL) that prevents
modification. You can, however, add new administration extensions to
existing IIS sections by adding new schema files.
Declaring Configuration Sections
After
the configuration section schema is in place, the configuration system
becomes capable of processing the section’s configuration data. However,
before the section can be used in the configuration file, it must also
be declared somewhere in the file’s configuration file hierarchy. This
is necessary to provide the Administrator with control over certain
behaviors of the configuration section that cannot be easily managed if
they are specified in the schema.
The declaration is performed by adding a <section>
element to the built-in <configSections> configuration section.
Each declaration may be nested within one or more section groups, which
are essentially grouping constructs for configuration sections (however,
sections cannot be nested inside one another). For example, the code
that follows is the declaration of the <defaultDocument>
configuration section, part of the system.webServer section group, located in ApplicationHost.config alongside the declarations of other IIS configuration sections.
Note
You can tell a bit about configuration sections
by looking at the section group to which they belong. For example, IIS
configuration sections that define global server configuration used by
Windows Activation Service (WAS), including the <sites> and
<applicationPools> configuration sections, reside in the system.applicationHost configuration section group. Web server configuration sections reside in the system.webServer section group. ASP.NET configuration sections are in the system.Web
section group. When you define your own section, you can create your
own section group (simply by declaring it in the configuration file) and
place it in one of the existing section groups, or you can just declare
your section in the top-level scope.
<configSections>
...
<sectionGroup name="system.webServer">
...
<section name="defaultDocument" overrideModeDefault="Allow" />
<sectionGroup name="system.webServer">
<configSections>
This declaration indicates that the
"defaultDocument" section can be used in the ApplicationHost.config file
and any configuration files further down in the hierarchy. It also
indicates that by default, lower configuration levels can later override
the section, effectively enabling control over this section to be
delegated to the application.
Important
Before editing configuration files, always
back them up so that you can restore configuration if necessary. By
default, the Application Host Helper Service automatically saves
snapshots of server-level configuration files every two minutes, which
may or may not be a sufficient level of protection for you.
To manually back up configuration before making a change, use the %windir%\System32\Inetsrv\Appcmd Add Backup <BackupName> command. To restore a backup made earlier, you can use the %windir%\System32\Inetsrv\Appcmd
Restore Backup <BackupName> command. To list the backups
available for restore that you made and ones made by Configuration
History Service, use the %windir%\System32\Inetsrv\Appcmd List Backups command.
Each declaration can specify the information shown in Table 2.
Table 2. Specifying Declarations
Declaration |
Description |
---|
Name |
The name of the configuration
section. Combined with the section group path, this name must match the
name of the section’s schema definition. This is required. |
allowDefinition |
The level at which configuration for
this section is allowed, including MachineOnly, MachineToApplication,
AppHostOnly, and Everywhere. This corresponds to parts of the
configuration hierarchy where the configuration section can be used.
Default is Everywhere. |
overrideModeDefault |
Whether the configuration for this section
can be defined at levels below the current file where it is declared.
Sections that set this to Deny effectively lock the configuration at
this level, preventing its delegation. Default is Allow. |
allowLocation |
Whether this section can be specified for a particular path using location tags. Default is true. |
type |
The .NET section handler type that is
responsible for processing this section. This is required for
configuration sections that are read by the .NET configuration system,
and therefore it is not needed for IIS configuration sections (unless
you plan to access them by using the .NET configuration system). None of
the IIS configuration sections define this attribute. If you declare
the configuration section in the .NET Framework’s Machine.config, root
Web.config, or distributed Web.config files inside your Web site
directory tree, you can set this attribute to the special System.Configuration.IgnoreSection type to avoid errors from the ASP.NET configuration system. |
requirePermission |
Specifies whether partial trust .NET applications can read the contents of this section by using the .NET System.Configuration (ASP.NET configuration system) or Microsoft.Web.Administration
(IIS configuration system) APIs. If set to false, these sections will
not be readable by applications running in partial trust. Default value
is true. |
Though the schema definitions for configuration sections are globally defined in the %windir%\System32\Inetsrv\Config\Schema directory, the section declarations can be located
at different levels of the configuration hierarchy, thereby making the
section available only at that level or below. By default, IIS 7.0
configuration hierarchy declares configuration sections as follows:
-
Framework Machine.config. Declares
.NET configuration sections available for all .NET programs, not just
ASP.NET. All .NET programs receive configuration from this file.
-
Framework root Web.config. Declares
ASP.NET-specific sections that are only available in Web applications.
When reading configuration, ASP.NET programs receive merged
configuration from Machine.config and this file.
-
ApplicationHost.config. Declares
IIS configuration sections. When reading configuration, IIS
configuration consumers receive configuration from the Framework
Machine.config, root Web.config, and this file.
-
Distributed Web.config. Contains
configuration settings for the site/application, and it sometimes
declares application-specific configuration sections (typically ASP.NET
configuration sections consumed via System.Configuration APIs).
Two other configuration files also declare
configuration sections: Redirection.config and Administration.config.
These files are not typically part of the configuration hierarchy for
Web applications, though they are used in specific scenarios. The
configuration system uses Redirection.config to redirect the
ApplicationHost.config accesses to a network location, in order to
enable shared configuration on a Web farm. IIS Manager uses
Administration.config to specify console-specific configuration,
including a list of IIS Manager extensions that the console loads .
Developers often use the section
declarations to control the default delegation state of configuration
sections, as well as to restrict the scope of where the configuration
can be specified. The former is done to prevent non-Administrators from
overriding certain configuration sections in Web.config files that they
have access to. The latter is done to restrict the usage of the
configuration section to the levels where it is actually read by the
corresponding Web server feature. For example, WAS and IIS worker
processes read the <sites> configuration section at the server
level only, and therefore this section is declared with allowDefinition = AppHostOnly.
Installing New Configuration Sections
Armed
with an understanding of schema definitions and declarations, adding a
new configuration section becomes a two-step process:
-
Register the section schema.
-
Declare the section in the desired configuration file.
To register the section schema, use the format described in IIS_schema.xml to create an XML file that contains the definition of the section. Then copy it to the %windir%\System32\Inetsrv\Config\Schema
directory. Because the IIS 7.0 configuration system is an In-Process
component, you will need to restart each process that needs to read the
new configuration section in order to force the process to load the new
schema file. This usually means recycling the target application pool or
restarting IIS services from a command prompt with Iisreset.exe, which
restarts worker processes in all application pools.
Note
To pick up the schema changes, you do not
technically need to restart all IIS services, because they will not
attempt to access your new section. It should be sufficient to restart
each IIS application pool that contains modules or application
components that use the new configuration section.
To declare the configuration
section, you need to add the section declaration element to the
<configSections> section at the level where you want the section
to become available. Most IIS configuration sections should be declared
in ApplicationHost.config, which enables them to be used at the server
level as well as in delegated application Web.config files.
If the section needs to be different for
different versions of the .NET Framework, you should declare it in the
.NET Framework Machine.config or root Web.config files. This is where
the rest of the .NET Framework and ASP.NET sections respectively are
declared. Web server features that access configuration inside the IIS
worker process automatically receive the configuration from the
Framework configuration files of the version specified by the
application pool’s managedRuntimeVersion attribute.
If you were planning to use the section only for
a particular Web site or application, you could declare it a Web.config
file inside the application. However, then you will not be able to read
this configuration for other applications nor will you be able to
specify the base configuration at the server level for configuration
reuse between applications.
That’s it. Once your section definition is
registered and the section is declared at the right configuration level,
you can now use it in the configuration files side-by-side with IIS
configuration.
Securing Configuration Sections
Unlike Web server modules, configuration
sections do not contain any code and therefore pose significantly less
risk to the system. At the time of this writing, we are not aware of
ways that you can reduce the security of your server by installing new
configuration sections. You can, however, introduce risk by installing
administration extensions that do contain code.
When
adding a new configuration section, you must consider a few concerns.
First, because configuration is intended to alter the behavior of the
server, it is important to maintain control over who can modify it and
how to avoid compromising the server’s operation.
By default, IIS 7.0 already
restricts the ability to change configuration in server-level
configuration files to Administrators. However, on servers where control
over the application content is delegated to non-Administrators, those
users can specify configuration in delegated Web.config files and
thereby override the configuration set at the server level for those
sites/applications. Even in cases where the server administrator
controls the application content, application components from third
parties can end up making undesired configuration settings. Because of
this, Administrators need to determine which configuration sections
should be used only at the server level, where the server administrator
maintains control, and which can be overridden at the application level.
The next section discusses controlling configuration delegation.
Second, the configuration data itself
may contain sensitive information, such as account passwords or
connection strings, and therefore you may want to take additional
precautions to prevent unintended disclosure of this information. You
can do this by requesting that certain parts of the new configuration
section be automatically encrypted when the configuration is written so
that the data is not persisted in clear-text form. This supplements the
protection afforded by access restrictions on the configuration files
and also protects the information from disclosure when the files are
transported off of the physical server. In this section, we’ll take a
closer look at doing this.
Controlling Configuration Delegation
If you are running a shared server on which
the server administrator is not the same person as the site or
application administrator, you should consider which configuration
sections can be overridden at the site or application level. You should
not allow delegation for any configuration section that can enable the
application to compromise the security of the server, dramatically
affect its performance, or gain access to other applications’
configuration or data.
The basic mechanism for controlling the
delegation of a new section is to prevent it from being overridden at a
lower level, unless it is explicitly unlocked by the Administrator.
This is done by specifying allowOverrideDefault = False in the section declaration. Most IIS configuration sections declared in ApplicationHost.config use this technique.
Note
You can also use the allowDefinition
attribute in the section declaration to limit the use of this section
to Machine or ApphostOnly scopes. However, it should never be used as a
mechanism for controlling delegation for the section because it cannot
be "unlocked" by the Administrator, unlike allowOverrideDefault. The allowDefinition
attribute is meant to restrict the use of the section to configuration
levels where the section is applicable based on how this section is
interpreted by the corresponding run-time consumer.
Once you specify allowOverrideDefault = False
in the section declaration, by default, lower configuration levels
cannot override this section. However, Administrators can always unlock
this section later to allow it to be specified at lower levels. To do
this, they wrap the configuration section by using a location tag that
can specify the overrideMode attribute to indicate that the section is locked or unlocked. The following example shows a configuration section with allowOverrideDefault="Deny" being unlocked:
<location path="" overrideMode="Allow">
<system.webServer>
<tracing>
<traceFailedRequests />
</tracing>
</system.webServer>
</location>
Setting overrideMode to "Deny" would lock the section. The path
attribute indicates which configuration path the location section is
used for, and it therefore determines the scope of the locking or
unlocking decision. The "" value in this case means unlock for all configuration levels, whereas a value of "Default Web Site/" would mean unlock for the site called "Default Web Site" only.
Instead of modifying
configuration directly, you can do it easily with the Appcmd command
line tool. For example, to unlock the <asp> section so that it can
be defined anywhere in the configuration hierarchy, use this code.
%windir%\system32\inetsrv\AppCmd unlock config /section:asp
In addition, the Administrator can unlock
this section for a specific site or application and then leave it locked
for others. For example, to unlock the <asp> section only for the
"Default Web Site/MyApp" application, use this code:
%windir%\system32\inetsrv\AppCmd unlock config "Default Web Site/MyApp"
/section:<SectionName>
By using the Appcmd Lock Config
command, the Administrator can also lock sections that are currently
unlocked. They can also manage the delegation state of configuration
sections by using IIS Manager.
Caution
Configuration delegation is intended
to control write access to configuration on shared servers, and it is
less applicable on dedicated servers where the server administrator
controls both the server and site configuration. However, it is good
practice to always restrict the delegation of configuration sections,
even on dedicated servers, and to unlock each configuration section
specifically whenever it needs to be used at the application level. This
reduces the risk of the application code accidentally specifying
undesired configuration settings in the future without the knowledge of
the Administrator. This is especially useful when installing
applications that come from third parties and that may end up including
undesired configuration in Web.config files.
In
some cases, section-level delegation control is not flexible enough,
and you’ll need to allow some parts of the configuration section to be
overridden while at the same time locking others. The configuration
system provides a number of mechanisms to accomplish this via attribute,
element, and collection locking.
Protecting Sensitive Configuration Data
The IIS 7.0 configuration system provides
an encryption mechanism that can protect sensitive information from
being accessed by an attacker if access is gained to the physical
configuration file. This is primarily intended to protect the
configuration data when it is transported off the machine and is not
properly protected by ACLs. While on the server, the ACLs on
configuration files are the main mechanism for securing access to
configuration.
You can use configuration encryption to
manually encrypt the value of any attribute in any IIS 7.0 configuration
section. However, if you know your configuration section contains
sensitive data, you should take advantage of automatic encryption by
marking the sensitive attributes in your configuration section schema to
always be encrypted. This is similar to the encrypted properties
support in the metabase in previous versions of IIS, except you can
easily take advantage of it to encrypt any part of your own
configuration section.
Note
The IIS 7.0 configuration system provides
attribute-level encryption support, unlike the ASP.NET configuration
system that uses section-level encryption. Though this is a more
flexible and sometimes more efficient mechanism (it enables you to
encrypt only the sensitive data in the section and leave the rest
unencrypted), it does have a few unfortunate side effects. The first is
that you cannot use Aspnet_regiis.exe or ASP.NET encryption to encrypt
IIS configuration sections.
The second, and arguably the most painful,
side effect is that you cannot use the IIS administration stack to
access ASP.NET configuration that has been encrypted with section-level
encryption. You can, however, use the Microsoft.Web.Administration APIs to access the IIS configuration sections from ASP.NET modules and .NET applications, instead of using System.Configuration. Finally, you cannot use IIS attribute-level encryption to encrypt .NET Framework or ASP.NET configuration sections.
This is done by including the encrypted
property to true on any of the attribute definitions in your
configuration section schema. Several built-in IIS 7.0 configuration
sections use this mechanism to insure that their sensitive content
remains encrypted. For example, the anonymousAuthentication section
marks the anonymous user password attribute as encrypted.
<sectionSchema
name="system.webServer/security/authentication/anonymousAuthentication">
...
<attribute name="password" type="string" caseSensitive="true"
encrypted="true" defaultValue="[enc:AesProvider::enc]" />
...
</sectionSchema>
By specifying the encrypted
property on the attribute schema definition, you insure that whenever
any configuration API or tool writes data to this attribute, it is
persisted in the encrypted form. You specify the default encryption
provider that the configuration system uses for this property by
referencing it through the default value, as in the previous example.
The encryption is transparent to the
writer. In addition, whenever this attribute is read by a caller that
has access to the configuration encryption key, the decryption is also
transparent so that the caller obtains the plain text value of this
attribute.
Caution
Although encryption protects your
configuration data from being accessed if someone gains physical access
to the file, it does not protect your configuration from code within the
IIS worker process. The configuration system inside the worker process
automatically decrypts any encrypted configuration (assuming the worker
process has access to the key container). Therefore, any code inside the
worker process can access the information. In fact, aside from using
application pool isolation to prevent access to configuration intended
for other application pools, there is no way to restrict configuration
access to a particular component within the worker process and not make
it available to other components in the process.