• Application Request Router (ARR) 3.0 is here!

    Good news, everyone! After a long time in Beta, ARR 3.0 is finally out and about. Thanks to tremendous work done by Jenny Lawrance from the IIS Dev team and Pandian Ramakrishnan from the IIS Test team, Application Request Router is here, and has some terrific new features.

    image

    Head over to the blog post on IIS.NET to read more about it, and you can also find the direct download link there. If you’re a fan of WebPI (Web Platform Installer), you can use that to find it as well:

    clip_image002

  • Registration complete!

    As I mentioned before, one of the things we had a particular interest in addressing with this release of IIS as part of Windows Server 2012 R2 was its scalability when handling a large number of sites. A key ingredient for this is what we call site “activation” or “registration”. This refers to the interaction between IIS and the Windows HTTP protocol stack (http.sys). When the system loads and the various services start, the HTTP stack and IIS work together to establish queues, which listen for incoming requests.

    With Windows 2012 released last year, as well as earlier versions of Windows, IIS was designed to “activate” (create queues) all the sites that were configured on it on startup. This is no big-deal if you have just a few sites on your server, but if you have hundreds or thousands of websites, this takes a while and consumes a lot of memory and kernel resources. To be clear, this does NOT refer to the action of spinning up a worker-process for a site. Creating a worker process only happens when a request for a site is received.

    If you are running a large number of sites on a single server, you will be happy to know that we have implemented a new feature called Dynamic Site Activation. When it is enabled, IIS doesn’t create queues and bindings for all sites in HTTP on startup. Instead, IIS creates one queue which listens for everything, and will create specific queues for specific sites only when a request actually arrives for it. This allows the IIS service to start much faster, and consume a lot less memory.

    As I said, this feature is more relevant for servers running a large number of sites, and so we have configured this to have a threshold of 100 sites. On servers with less sites than that, this will be off by default. If the server does have 100 sites or more, it will not create the queues for them upon startup, and if you observe the kernel paged pool memory usage, it should be quite visible. It will also result in IIS taking noticeably less time to restart as it won’t need to release all of the registered queues and bindings with HTTP.

    If you are running a lower number of sites, you can configure the threshold to a lower value, though I should note that the performance difference is lesser on a smaller number of sites, and at some point it may even be a tad slower.

    To see this feature in action, run the command netsh http show servicestate on your server. This command shows a list of queues (sites that are “registered”). For example:

    clip_image001

    On a Windows 2012 server, you would see a list of all the site you have configured. On a Windows 2012 R2 server with DSA active (has a number of websites that is over the threshold), the number of queues will typically be lower, and the command will only show the registered queues. If you don’t have a lot of sites and you want to explore this, simply set the threshold to a number lower than your total number of sites, and restart IIS. The configure this:

    1. In the IIS console, Go to Configuration Editor:

    clip_image002

    2. Go to weblimits

    clip_image003

    3. Change dynamicRegistrationThreshold value to one that suits your needs:

    clip_image004

    4. Restart IIS

     

    Like this feature? Go ahead and download the preview of Windows Server 2012 R2 here. We here in the IIS Dev team hope you enjoy it!

  • Log a rhythm

    Even before the day logs were just a piece of wood used to measure the speed of a ship, captains have looked for ways to know what’s going on under the deck, and with the new version of IIS in Windows Server 2012 R2 we have kicked the logging ability of IIS multiple notches up.

    IIS’ logging abilities have always been above average and highly customizable, but now, it’s even better. We have introduced an ability for the administrator to configure IIS to log multiple fields that were previously available only with packet-level inspection. When configuring logging, the administrator can now add custom fields that store:

    1. Request headers

    2. Response headers

    3. Server Variables

    For example, until now, you could log the port the client was connecting to…but not the port it was connecting from. Now you can do this easily, as well as many other fields. To do so, you click on Logging (either at the server level, or site level) and click on Select Fields:

    clip_image002

    clip_image004

    As you can see, this lists the fields that you are probably familiar from previous releases…but also the custom fields at the bottom. To add a field, click on Add Field, give your custom field a name, and select from the drop downs:

    clip_image006

    The other groups of items provide the following selection:

    Request Headers

    Response Headers

    Server Variables

    Accept
    Accept-Charset
    Accept-Encoding
    Authorization
    Cache-Control
    Connection
    Content-length
    Content-MD5
    Content-Type
    Date
    Expect
    From
    Host
    If-Match
    If-Modified-Since
    If-None-Match
    If-Range
    If-Unmodified-Since
    Max-Forwards
    Pramga
    Proxy-Authorization
    Range
    Referer
    TE
    Upgrade
    User-Agent
    Via
    Warning

    Accept-Ranges
    Content-Type
    ETag
    Last-Modified
    Server

    ALL_HTTP
    ALL_RAW
    APPL_MD_PATH
    APPL_PHYSICAL_PATH
    AUTH_PASSWORD
    AUTH_TYPE
    AUTH_USER
    CERT_COOKIE
    CERT_FLAGS
    CERT_ISSUER
    CERT_KEYSIZE
    CERT_SECRETKEYSIZE
    CERT_SERIALNUMBER
    CERT_SERVER_ISSUER
    CERT_SERVER_SUBJECT
    CERT_SUBJECT
    CONTENT_LENGTH
    CONTENT_TYPE
    GATEWAY_INTERFACE
    HTTP_ACCEPT
    HTTP_ACCEPT_ENCODING
    HTTP_ACCEPT_LANGUAGE
    HTTP_CONNECTION
    HTTP_COOKIE
    HTTP_HOST
    HTTP_METHOD
    HTTP_REFERER
    HTTP_URL
    HTTP_USER_AGENT
    HTTP_VERSION
    HTTPS
    HTTPS_KEYSIZE
    HTTPS_SECRETKEYSIZE
    HTTPS_SERVER_ISSUER
    HTTPS_SERVER_SUBJECT
    INSTANCE_ID
    INSTANCE_META_PATH
    LOCAL_ADDR
    LOGON_USER
    PATH_INFO
    PATH_TRANSLATED
    QUERY_STRING
    REMOTE_ADDR
    REMOTE_HOST
    REMOTE_PORT
    REMOTE_USER
    REQUEST_METHOD
    SCRIPT_NAME
    SERVER_NAME
    SERVER_PORT
    SERVER_PORT_SECURE
    SERVER_PROTOCOL
    SERVER_SOFTWARE
    UNMAPPED_REMOTE_USER

    In addition to the pre-populated items, you can also type in your own custom field data. For example, a common challenge for security people and network administrator is the need to record the IP of connecting clients. On servers that are directly on the network, this is not a problem, but if the web server is front-ended by a load balancer, the logged IP will be the IP of the load balancer itself. Load balancers can usually be configured to forward the IP of the originating client in a custom HTTP Header named “X-FORWARDED-FOR” (http://en.wikipedia.org/wiki/X-Forwarded-For). The Load Balancer, before forwarding the request, would attach a custom request header by that name which contains the IP of the client this request was forwarded for. By adding a custom request-header field like this, we can record this in the IIS logs and use the data for whatever purpose we need:

    clip_image014

    Once you add in any additional fields, IIS will create log files with _x appended to the file name, which indicates that these are log files containing the extra fields:

    image

    The enhanced logging is managed by a new service in Windows 2012 R2 called “W3C Logging Service”. As opposed to previous generations of IIS, where the HTTP protocol stack would be doing the logging, the new service sits in-between, which allows it to collect the headers and put them in the log. This service is stopped by default and set to “manual” startup. When you add a field to enhanced logging and the site receives a request, the service will be started (although the startup mode remains on Manual) and logging the enhanced fields will commence.

    image

    Like it? Download the preview of Windows Server 2012 R2 here, and enjoy!

  • Hook me up!

    Who doesn’t LOVE reading log files? Probably those who have really busy servers that generate hundreds of mega-bytes of logs every minute. Even though the log format of IIS is standardized and many tools can parse them easily, this still presents three challenges:

    1. Even the best tools cannot process the logs in real time, because the server keeps updating the text files as long as requests are coming in.
    2. Even if you only read the content of the log files, it still takes IIS some time to flush log lines to disk, so you’re at least a few seconds behind.
    3. On a very busy server, processing the text-based logs can be too difficult to mine the information you need even with advanced text-processing tools.

    With the new version of IIS in Windows Server 2012 R2, we have enabled the logs to use ETW (Event Tracing for Windows). ETW is a special hook that allows the logging to be tracked in real time with special tools. In IIS, here’s how you enable ETW logging:

    image

    Once a request is received by IIS, the event viewer will show it immediately (as opposed to text-file based logging, in which flushing to the log takes approximately 30 seconds). In addition to this, you can hook into the ETW provider directly using tools such as Message Analyzer. Message Analyzer, currently in Beta 3, can hook directly into ETW, capture events in real time and filter the output. By configuring your filters cleverly, you can easily find the information you need even on a server that handles thousands of requests per second.

    To configure Message Analyzer to hook into ETW, follow these steps:

    1. open Message Analyzer

    2. Go to Capture/Trace

    3. In the top-right corner, in the Search and add providers input box, type in Microsoft-windows-IIS-logging (you don’t have to type in the whole thing…just type “iis-l” to get to it fast

    image

    4. Optionally, add a capture filter. For example, if you are trying to track the access by a specific iPad to your Exchange server ActiveSync, you can create a filter for that specific device ID, which will appear in the URL. To do so find the device ID, and create a filter for it. A typical iPad request to ActiveSync will look like this:

    http://www.contoso.com/Microsoft-Server-ActiveSync?User=sbbgpowl&DeviceId=ApplDLFHXGSG12DY&DeviceType=iPad&Cmd=Ping

    Setting your filter to:

    Contains==”ApplDLFHXGSG12DY”

    Will show only requests from this device. Setting the filter to “iPad” will show requests from all iPad devices. Similarly, you can filter for any of the text in the custom fields you may have configured in IIS enhanced logging.

    5. Click start-with to start the capture

    Now, the analyzer will show any incoming requests to IIS that match your filter expression. Clicking on a request will show the details. For example:

    image

    As you can see, the details pane on the bottom-left shows the fields that were captured. The filtering abilities of Message Analyzer are very useful for servers that are handling a large amount of traffic. You can set your filters to run during capture, which is ideal, if you know what you’re looking for. You can also set the filters later, once you know you got what you need. For example, the Quick Filter button on the top-right allows you to filter for a specific time using a neat slider:

    image

    And beyond this…the things you can do are endless.

    Like it? Download the Preview release of Windows Server 2012 R2 and enjoy!

  • Dynamic IP restrictions deny action settings.

    Like most settings in IIS, the options for deny-action settings in Dynamic IP restrictions can be adjusted from the IIS UI, or via PowerShell. In the UI, this is how it looks like:

    clip_image002

    However, if you tried to adjust this settings using PowerShell, you might find that the settings don’t appear to show up in the management console. For example, if you run this PowerShell command:

    Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -filter "system.webServer/security/dynamicIpSecurity" -name "denyAction" -value "AbortRequest"

    The command will complete successfully, and if you used the Get-WebConfigurationProperty command to query it, will return the value you have set, but the UI will still show the “old” value.

    This might seem weird, but in reality, this is exactly the way its supposed to behave. You see, in the current version of IIS, the DenyAction property has two values. One is for DynamicIPSecurity, and another for ipSecurity. In the configuration file (AppicationHost.config), this looks like this:

    <security>
    <access sslFlags="None" />
    <applicationDependencies />
    <authentication>
    <anonymousAuthentication enabled="true" userName="IUSR" />
    <basicAuthentication />
    <clientCertificateMappingAuthentication />
    <digestAuthentication />
    <iisClientCertificateMappingAuthentication />
    <windowsAuthentication />
    </authentication>
    <authorization />
    <ipSecurity allowUnlisted="true" denyAction="AbortRequest" />
    <isapiCgiRestriction />
    <requestFiltering>
    <fileExtensions allowUnlisted="true" applyToWebDAV="true" />
    <verbs allowUnlisted="true" applyToWebDAV="true" />
    <hiddenSegments applyToWebDAV="true">
    <add segment="web.config" />
    </hiddenSegments>
    </requestFiltering>
    <dynamicIpSecurity denyAction="AbortRequest" />

    If you change the configuration from the IIS manager UI, the configuration is adjusted for both, but with PowerShell, you need to adjust both using the following commands:

    Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -filter "system.webServer/security/dynamicIpSecurity" -name "denyAction" -value " AbortRequest "

    Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -filter "system.webServer/security/ipSecurity" -name "denyAction" -value "AbortRequest"

    If you fail to do so, you will end up with an inconsistent configuration.

    Cheers to Carl R for his help with this post!